i'm new to file i/o so i'm sorry if this is a pretty bad question.
Currently I have an add method/main method and a person class my outputstream is working fine in the add method: This is at the top of the method
FileOutputStream myFile = null;
try {
myFile = new FileOutputStream("txt123.txt");
} catch (FileNotFoundException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(myFile);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
And I then have this twice because there are two types of people that can be added
oos.writeObject(person);
oos.close();
System.out.println("Done");
So my question, how do i get the input working and finally where do i put it, in the add method or the main method, I read how to do what i done here: http://www.mkyong.com/java/how-to-write-an-object-to-file-in-java/
He also has a guide on reading in the objects but I cant seem to get it working
Thanks!
You would be reading the file you just created like this:
ObjectInputStream in =
new ObjectInputStream(new FileInputStream("txt123.txt"));
// terrible file name, because this is binary data, not text
try{
Person person = (Person) in.readObject();
finally{
in.close();
}
You can combine the ObjectOutputStream with the FileOutputStream as follows. I'm also guessing you need to place the read/write code in one place to allow re-use. Here's a simple example with the read/write in a DAO.
public static class Person implements Serializable {
private String name;
public Person(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
#Override
public String toString() {
return name;
}
}
public static class PersonDao {
public void write(Person person, File file) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(file));
oos.writeObject(person);
oos.close();
}
public Person read(File file) throws IOException,
ClassNotFoundException {
ObjectInputStream oos = new ObjectInputStream(new FileInputStream(
file));
Person returnValue = (Person) oos.readObject();
oos.close();
return returnValue;
}
}
public static void main(String[] args) throws IOException,
ClassNotFoundException {
PersonDao personDao = new PersonDao();
Person alice = new Person("alice");
personDao.write(alice, new File("alice.bin"));
Person bob = new Person("bob");
personDao.write(bob, new File("bob.bin"));
System.out.println(personDao.read(new File("alice.bin")));
System.out.println(personDao.read(new File("bob.bin")));
}
Related
I need to write a class that has two static methods: writeFile and readFile. However, after I do my readFile(), it returns nothing.
class writereadFile {
public static void writeFile(ArrayList<Object> list, File file){
try {
try (FileOutputStream fos = new FileOutputStream(file);ObjectOutputStream oos = new ObjectOutputStream(fos)) {
oos.writeObject(list);
oos.close();
}
}catch(IOException e){e.getMessage();}
}
public static ArrayList<Object> readFile(ArrayList<Object>list, File file){
try {
try (FileInputStream fis = new FileInputStream(file);ObjectInputStream ois = new ObjectInputStream(fis)) {
Object o = ois.readObject();
list = (ArrayList<Object>) o;
ois.close();
}
}catch(IOException | ClassNotFoundException e){e.getMessage();}
System.out.println(list);
return list;
}
}
EDIT:
This my class for testing. My object is an arraylist of custom objects if you need the custom object just comment.
class main {
public static void main(String[] args) {
Date date = new Date();
Book b1 = new Book("abc", "Phi", true, date, null);
Book b2 = new Book("cba", "Someone", true, date, null);
Books booklist = new Books();
booklist.add(b1);
booklist.add(b2);
File filetoDo = new File("book.txt");
//write arraylist into file
writereadFile.writeFile(booklist, filetoDo);
//clear the arraylist
booklist.clear();
//read book from file
writereadFile.readFile(booklist, filetoDo);
System.out.println(booklist);
}
}
Your test should read:
bookList = writereadFile.readFile(booklist, filetoDo);
and, by the way, you should really refactor your readFile method to simply:
public static ArrayList<Object> readFile(File file)
You can't modify the argument reference like that, since Java is always pass-by-value call semantics. (You could modify the list argument contents inside the function, but that's not what you are doing.)
If you are using Java 8 try using Streams:
public static readFile(String filePath) {
List<Object> list = new ArrayList<>();
try (Stream<String> stream = Files.lines(Paths.get(filePath))) {
stream.forEach(list::add);
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
I'm playing around this topic a bit on my own, so below you can find some code snippets that might help you.
Examples are very short and simple, so I hope you will not just use e.printStackTrace() in your code :)
public class ExternalIO {
private ExternalIO() {
}
public static ObjectOutputStream objectOutputStream(String basePath, String pathToFile) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream(createFileIfDoesNotExist(absolutePath(basePath, pathToFile)));
return new ObjectOutputStream(fileOutputStream);
}
public static ObjectInputStream objectInputStream(String basePath, String pathToFile) throws IOException {
FileInputStream fileInputStream = new FileInputStream(absolutePath(basePath, pathToFile));
return new ObjectInputStream(fileInputStream);
}
private static File createFileIfDoesNotExist(String absolutePath) throws IOException {
File file = new File(absolutePath);
if (file.exists()) {
return file;
}
file.getParentFile().mkdirs();
file.createNewFile();
return file;
}
private static String absolutePath(String basePath, String pathToFile) {
return Paths.get(basePath, pathToFile).toAbsolutePath().toString();
}
}
output usage:
List<ItemType> input = null; //create your input list here
try (ObjectOutputStream objectOutputStream = ExternalIO.objectOutputStream(CONFIG, FILENAME)) {
objectOutputStream.writeObject(input);
} catch (Exception e) {
e.printStackTrace();
}
input usage:
try (ObjectInputStream objectInputStream = ExternalIO.objectInputStream(CONFIG, FILENAME)) {
return (List<ItemType>) objectInputStream.readObject();
} catch (Exception e) {
e.printStackTrace();
}
hope that helps ; )
I've pair the code down to the methods I am having a problem, with. It 'seems' to work until I try to load the file again, and it comes up with nothing in it. (I have not fully understood how to clear the ArrayList before performing the 2nd load, but that is for later).
I am sorry if this is hidden somewhere under some other nomenclature I also have not learned yet, but this is a project that is due tomorrow and I am at my wit's end.
import java.util.*;
import java.io.*;
public class MainATM3 {
public static ArrayList<ClientAccount> accounts = new ArrayList<ClientAccount>();
public static ClientAccount editBankAccount = new ClientAccount("placeholder",1234,1);;
public static void main(String[] args) {
// Create ATM account ArrayList
ArrayList<ClientAccount> accounts = new ArrayList<ClientAccount>();
// Get Account data from files
initialLoadATMAccounts(accounts);
System.out.println("Loaded "+accounts.size());
System.out.println("before Array "+(accounts.size()));
accounts.add(0,new ClientAccount("Jess",500,1830));
accounts.add(1,new ClientAccount("Mary",1111.11,7890));
System.out.println("after Array "+(accounts.size()));
saveATMAccounts(accounts);
System.out.println("saved "+(accounts.size()));
initialLoadATMAccounts(accounts);
System.out.println("Loaded "+accounts.size());
System.out.println("Logged Out");
}
// Save ArrayList of ATM Objects //call by: saveATMAccounts(accounts);
public static void saveATMAccounts(ArrayList<ClientAccount> saveAccounts) {
FileOutputStream fout = null;
ObjectOutputStream oos = null;
try{
fout=new FileOutputStream("ATMAccounts.sav");
oos = new ObjectOutputStream(fout);
oos.writeObject(accounts);
System.out.println("objects written "+(accounts.size()));
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (fout != null) {
try {
fout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// INITIAL Load ArrayList of ATM Objects //call by: initialLoadATMAccounts(accounts);
public static void initialLoadATMAccounts(ArrayList<ClientAccount> loadAccounts){
FileInputStream fIS = null;
ObjectInputStream oIS = null;
try{
fIS=new FileInputStream("ATMAccounts.sav");
oIS = new ObjectInputStream(fIS);
ArrayList<ClientAccount> loadAccounts = (ArrayList<ClientAccount>) oIS.readObject();
oIS.close();
fIS.close();
}
catch(Exception exc){
exc.printStackTrace();
}
}
}
import java.io.Serializable;
public class ClientAccount implements Serializable {
public String accountName;
public double accountBalance;
public int accountPIN;
public ClientAccount(String accountName, double accountBalance, int accountPIN){
this.accountName=accountName;
this.accountBalance=accountBalance;
this.accountPIN=accountPIN;
}
// Account Name Methods
public String getAccountName() {
return accountName;
}
public void setAccountName(String name) {
accountName = name;
}
// Account Balance Methods
public double getAccountBalance() {
return accountBalance;
}
public void setAccountBalance(double balance) {
accountBalance = balance;
}
// PIN Methods
public int getAccountPIN() {
return accountPIN;
}
public void setAccountPIN(int newPIN) {
accountPIN = newPIN;
}
}
Instead of passing the desired array to initialLoadATMAccounts as param you should return the new, loaded array:
public static List<ClientAccount> initialLoadATMAccounts(){
FileInputStream fIS = null;
ObjectInputStream oIS = null;
try{
fIS=new FileInputStream("ATMAccounts.sav");
oIS = new ObjectInputStream(fIS);
ArrayList<ClientAccount> loadAccounts = (ArrayList<ClientAccount>) oIS.readObject();
oIS.close();
fIS.close();
return loadAccounts;
}
catch(Exception exc){
exc.printStackTrace();
}
}
BTW: A IDE like eclipse would have issued a warning where you overwrite the param loadAccounts.
Recieving the error:
java.io.NotSerializableException
even after implementing Serializable.
I'm simply trying to serialize a Survey object. Here is my code, does anyone have an idea why I am receiving this error?
public void loadData(Survey survey, Test test, Boolean isSurvey) throws FileNotFoundException {
...
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName));
Survey s = (Survey) ois.readObject();
ois.close();
System.out.println("list size = " + s.questions);
} catch (Exception e) {
e.printStackTrace();
}
}
public void saveData(Survey survey, Test test, Boolean isSurvey, String fileName) {
...
if (isSurvey) {
try {
FileOutputStream fileOut = new FileOutputStream("surveys/" + fileName);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(survey);
out.close();
fileOut.close();
} catch (IOException ex) {
}
} else {
try {
FileOutputStream fileOut = new FileOutputStream("tests/" + fileName);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(test);
out.close();
fileOut.close();
} catch (IOException ex) {
}
}
}
EDIT: Added survey class. My Question class, Main class, and Input class both implement Serializable
package Survey;
import java.io.Serializable;
import java.util.ArrayList;
import IO.Input;
import Question.Question;
public class Survey implements Serializable{
private static final long serialVersionUID = 1L;
protected Main main = new Main();
protected Input input = new Input();
protected String name;
public ArrayList<Question> questions = new ArrayList<Question>();
public void setName() {
...
}
public void displayName() {
...
}
public void displayQuestions() {
...
}
public void mainMenu() {
...
}
public void addQuestionMenu() {
...
}
}
I am writing a program in Java which displays a range of afterschool clubs (E.G. Football, Hockey - entered by user). The clubs are added into the following ArrayList:
private ArrayList<Club> clubs = new ArrayList<Club>();
By the followng Method:
public void addClub(String clubName) {
Club club = findClub(clubName);
if (club == null)
clubs.add(new Club(clubName));
}
'Club' is a class with a constructor - name:
public class Club {
private String name;
public Club(String name) {
this.name = name;
}
//There are more methods in my program but don't affect my query..
}
My program is working - it lets me add a new Club Object into my arraylist, i can view the arraylist, and i can delete any that i want etc.
However, I now want to save that arrayList (clubs) to a file, and then i want to be able to load the file up later and the same arraylist is there again.
I have two methods for this (see below), and have been trying to get it working but havent had anyluck, any help or advice would be appreciated.
Save Method (fileName is chosen by user)
public void save(String fileName) throws FileNotFoundException {
String tmp = clubs.toString();
PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));
pw.write(tmp);
pw.close();
}
Load method (Current code wont run - File is a string but needs to be Club?
public void load(String fileName) throws FileNotFoundException {
FileInputStream fileIn = new FileInputStream(fileName);
Scanner scan = new Scanner(fileIn);
String loadedClubs = scan.next();
clubs.add(loadedClubs);
}
I am also using a GUI to run the application, and at the moment, i can click my Save button which then allows me to type a name and location and save it. The file appears and can be opened up in Notepad but displays as something like Club#c5d8jdj (for each Club in my list)
You should use Java's built in serialization mechanism.
To use it, you need to do the following:
Declare the Club class as implementing Serializable:
public class Club implements Serializable {
...
}
This tells the JVM that the class can be serialized to a stream. You don't have to implement any method, since this is a marker interface.
To write your list to a file do the following:
FileOutputStream fos = new FileOutputStream("t.tmp");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(clubs);
oos.close();
To read the list from a file, do the following:
FileInputStream fis = new FileInputStream("t.tmp");
ObjectInputStream ois = new ObjectInputStream(fis);
List<Club> clubs = (List<Club>) ois.readObject();
ois.close();
As an exercise, I would suggest doing the following:
public void save(String fileName) throws FileNotFoundException {
PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));
for (Club club : clubs)
pw.println(club.getName());
pw.close();
}
This will write the name of each club on a new line in your file.
Soccer
Chess
Football
Volleyball
...
I'll leave the loading to you. Hint: You wrote one line at a time, you can then read one line at a time.
Every class in Java extends the Object class. As such you can override its methods. In this case, you should be interested by the toString() method. In your Club class, you can override it to print some message about the class in any format you'd like.
public String toString() {
return "Club:" + name;
}
You could then change the above code to:
public void save(String fileName) throws FileNotFoundException {
PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));
for (Club club : clubs)
pw.println(club); // call toString() on club, like club.toString()
pw.close();
}
In Java 8 you can use Files.write() method with two arguments: Path and List<String>, something like this:
List<String> clubNames = clubs.stream()
.map(Club::getName)
.collect(Collectors.toList())
try {
Files.write(Paths.get(fileName), clubNames);
} catch (IOException e) {
log.error("Unable to write out names", e);
}
This might work for you
public void save(String fileName) throws FileNotFoundException {
FileOutputStream fout= new FileOutputStream (fileName);
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(clubs);
fout.close();
}
To read back you can have
public void read(String fileName) throws FileNotFoundException {
FileInputStream fin= new FileInputStream (fileName);
ObjectInputStream ois = new ObjectInputStream(fin);
clubs= (ArrayList<Clubs>)ois.readObject();
fin.close();
}
ObjectOutputStream.writeObject(clubs)
ObjectInputStream.readObject();
Also, you 'add' logic is logically equivalent to using a Set instead of a List. Lists can have duplicates and Sets cannot. You should consider using a set. After all, can you really have 2 chess clubs in the same school?
To save and load an arraylist of
public static ArrayList data = new ArrayList ();
I used (to write)...
static void saveDatabase() {
try {
FileOutputStream fos = new FileOutputStream("mydb.fil");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(data);
oos.close();
databaseIsSaved = true;
}
catch (IOException e) {
e.printStackTrace();
}
} // End of saveDatabase
And used (to read) ...
static void loadDatabase() {
try {
FileInputStream fis = new FileInputStream("mydb.fil");
ObjectInputStream ois = new ObjectInputStream(fis);
data = (ArrayList<User>)ois.readObject();
ois.close();
}
catch (IOException e) {
System.out.println("***catch ERROR***");
e.printStackTrace();
}
catch (ClassNotFoundException e) {
System.out.println("***catch ERROR***");
e.printStackTrace();
}
} // End of loadDatabase
I want to store an object from my class in file, and after that to be able to load the object from this file. But somewhere I am making a mistake(s) and cannot figure out where. May I receive some help?
public class GameManagerSystem implements GameManager, Serializable {
private static final long serialVersionUID = -5966618586666474164L;
HashMap<Game, GameStatus> games;
HashMap<Ticket, ArrayList<Object>> baggage;
HashSet<Ticket> bookedTickets;
Place place;
public GameManagerSystem(Place place) {
super();
this.games = new HashMap<Game, GameStatus>();
this.baggage = new HashMap<Ticket, ArrayList<Object>>();
this.bookedTickets = new HashSet<Ticket>();
this.place = place;
}
public static GameManager createManagerSystem(Game at) {
return new GameManagerSystem(at);
}
public boolean store(File f) {
try {
FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(games);
oos.writeObject(bookedTickets);
oos.writeObject(baggage);
oos.close();
fos.close();
} catch (IOException ex) {
return false;
}
return true;
}
public boolean load(File f) {
try {
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis);
this.games = (HashMap<Game,GameStatus>)ois.readObject();
this.bookedTickets = (HashSet<Ticket>)ois.readObject();
this.baggage = (HashMap<Ticket,ArrayList<Object>>)ois.readObject();
ois.close();
fis.close();
} catch (IOException e) {
return false;
} catch (ClassNotFoundException e) {
return false;
}
return true;
}
.
.
.
}
public class JUnitDemo {
GameManager manager;
#Before
public void setUp() {
manager = GameManagerSystem.createManagerSystem(Place.ENG);
}
#Test
public void testStore() {
Game g = new Game(new Date(), Teams.LIONS, Teams.SHARKS);
manager.registerGame(g);
File file = new File("file.ser");
assertTrue(airport.store(file));
}
}
The solution of this problem is that when you are using other objects, let say class A, into a collection like HashMap and want to serialize the HashMap object, then implement the interface Serializable for class A like this:
class A implements Serializable {
}
...
HashMap<Integer,A> hmap;
...
Otherwise that object will not be serializable.
I hope it will solve this problem now.
Try oos.flush() before you close it.
Please remenber that the whole object graph is persisted during serialize. If you have some references to GUI classes for example, you either have to make them serializable, too, or tag them as "transient", so Java won't serialize them.