I'm having an issue loading objects back from my .dat file. I believe they're writing properly. I feel like the solution is pretty easy, but I've been banging my head against the wall for hours over this. Neither methods are throwing any errors. If I run the save2 method, my output is this:
Obj written: [Faculty] Professor John Example [x] 123-010-1010 [x] ID: 1 [x] Salary: $63,605.00
Obj written: [Student] Ron Doe [x] 123-222-2332 [x] Major: Culinary [x] ID: 2 [x] GPA: 3.7 [x] courseBag
Obj written: [Student] Bon Jovi [x] 123-372-4383 [x] Major: Computer Science [x] ID: 3 [x] GPA: 2.85 [x] courseBag
This is the output of running the load2 method:
FOUND A STUDENT---------
[PeopleBag]: Loaded people_bag2.dat into memory successfully.
But the objects aren't getting placed into memory. There's 1 faculty and 2 students that were saved. The load method isn't even picking up the faculty member.
Here's my save method:
public void save2() {
String fileName;
FileOutputStream outFile;
ObjectOutputStream outStream;
Person tempPerson;
fileName = "people_bag2.dat";
try {
outFile = new FileOutputStream(fileName);
outStream = new ObjectOutputStream(outFile);
for (int i = 0; i < personArray.length; i++) {
if(personArray[i] != null) {
tempPerson = personArray[i];
outStream.writeObject(tempPerson); // this one line writes an object
if(Utilities.DEBUG)
System.out.println("Obj written: "+tempPerson);
}
}
outStream.close();
if(Utilities.DEBUG)
System.out.println("[PeopleBag]: Saved bag to "+fileName+" successfully.");
} catch (IOException e) {
System.out.println(e);
}
}
Here's my load method:
public void load2() {
String fileName;
FileInputStream inFile;
ObjectInputStream inStream = null;
Student tempStudent;
Faculty tempFaculty;
fileName = "people_bag2.dat";
try {
inFile = new FileInputStream(fileName);
inStream = new ObjectInputStream(inFile);
while (true) {
if(inStream.readObject().toString().startsWith("[Student")) {
System.out.println("FOUND A STUDENT---------");
tempStudent = (Student) inStream.readObject();
Student person = new Student(tempStudent.getFirstName(), tempStudent.getLastName(), tempStudent.getPhoneNumber(), tempStudent.getMajor(), tempStudent.getCourseBag());
add(tempStudent); //add(person) doesn't work either
//if(Utilities.DEBUG)
System.out.println("tempStudent: "+tempStudent.toString() + "\n");
}
if(inStream.readObject().toString().startsWith("[Faculty")) {
System.out.println("FOUND A FACULTY---------");
tempFaculty = (Faculty) inStream.readObject();
//String firstName, String lastName, String phoneNumber, String title, double salary
Faculty f = new Faculty(tempFaculty.getFirstName(), tempFaculty.getLastName(), tempFaculty.getPhoneNumber(), tempFaculty.getTitle(), tempFaculty.getSalary());
add(f); //add the person to the bag
}
}
} catch (EOFException e) { // catch EOF
try {
if(Utilities.DEBUG)
System.out.println("[PeopleBag]: Loaded "+fileName+" into memory successfully.");
inStream.close();
} exceptions blah blah
}
Also he add(Person... person) method works fine. I have a working method which loads the data from a text file. I have a similar method to load courses, except without the inStream.readObject().toString... if-statement, and it works fine. I think the issue has to do with the inStream.readObject().toString().startsWith( faculty or student).
This is a load method for courses, which works fine:
public void load() {
String fileName = "course_bag.dat";
FileInputStream inFile;
ObjectInputStream inStream = null;
Course tempCourse;
try {
inFile = new FileInputStream(fileName);
inStream = new ObjectInputStream(inFile);
while (true) {
tempCourse = (Course)inStream.readObject();
//String courseTitle, String crn, Textbook textbook, double credits
Course txtbk = new Course(tempCourse.getCourseTitle(), tempCourse.getCrn(), tempCourse.getTextbook(), tempCourse.getCredits());
add(txtbk);
}
} catch (FileNotFoundException e) {
System.out.println("File named "+ fileName +" not found.\n");
} catch (EOFException e) { // catch EOF
try {
if(Utilities.DEBUG)
System.out.println("[CourseBag]: Loaded "+fileName+" into memory successfully.");
inStream.close();
} catch (IOException ex) { }
} catch (IOException e) {
System.out.println(e);
} catch (ClassNotFoundException e) {
System.out.println(e);
}
}
Instead of reading an object and converting it to a string and throwing it away and seeing what the string starts with and then reading another object, you should read one object and use instanceof to see what it actually was.
Related
I'm trying to add items from the console input and scanner input to arraylists in java.
(To run the program user types Program ID)
The problem is that each time I run the program the contents of the arraylists update to only what has been entered that time. I would like the arraylists to contain all of the inputs that have been entered.
public class User{
private static List<String> listNames = new ArrayList<String>();
private static List<Integer> listIds = new ArrayList<Integer>();
public static void main(String[] args)
{
int tempID = 5000;
if (args.length>0) tempID= Integer.parseInt(args[0]);
System.out.println("Login "+tempID);
Scanner scanner = new Scanner(System.in);
System.out.print("Enter your Name : ");
tempName = scanner.nextLine();
User n = new User();
n.ID= tempID;
n.name = tempName;
listIds.add(n.ID);
listNames.add(n.name);
}
}
}
Does anyone know if this is possible?
Everytime you run the program it is going to initialize a different array. To solve this, you can store your data in a database such as MySQL or Oracle. But a more efficient way to solve this is that to save your ArrayList as an object locally using java.io.ObjectInputStream and java.io.ObjectOutputStream
I wrote the following 2 functions
public static ArrayList<Object> loadArrayList(String filename)
{
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream(filename));
ArrayList<Object> arr = (ArrayList<Object>) ois.readObject();
return arr;
} catch (IOException e) {
e.printStackTrace();
return null;
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
} finally {
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void saveArrayList(ArrayList<Object> arr, String filename)
{
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream(filename));
oos.writeObject(arr);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Call saveArrayList with the first argument is your ArrayList instance and the second argument the filename. You can then load from your local file system using the loadArrayList method with the argument is your filename.
In your case, just call the saveArrayList method when your user exits the program and call the loadArrayList to get all your elements from the previous inputs to resume the user's progress
Every time you compile your program you create new Arrays. So you need another way of saving your inputs like in a SQL Database or you can run your program infinitely with a loop and ask each time for a new entry and collect it with the scanner like you already did but with that method, you can do nothing with the array entries because your asking for entries never stops.
I have a problem on my code; basically I have an array containing some key:
String[] ComputerScience = { "A", "B", "C", "D" };
And so on, containing 40 entries.
My code reads 900 pdf from 40 folder corresponding to each element of ComputerScience, manipulates the extracted text and stores the output in a file named A.txt , B.txt, ecc ...
Each folder "A", "B", ecc contains 900 pdf.
After a lot of documents, an exception "Too many open files" is thrown.
I'm supposing that I am correctly closing files handler.
static boolean writeOccurencesFile(String WORDLIST,String categoria, TreeMap<String,Integer> map) {
File dizionario = new File(WORDLIST);
FileReader fileReader = null;
FileWriter fileWriter = null;
try {
File cat_out = new File("files/" + categoria + ".txt");
fileWriter = new FileWriter(cat_out, true);
} catch (IOException e) {
e.printStackTrace();
}
try {
fileReader = new FileReader(dizionario);
} catch (FileNotFoundException e) { }
try {
BufferedReader bufferedReader = new BufferedReader(fileReader);
if (dizionario.exists()) {
StringBuffer stringBuffer = new StringBuffer();
String parola;
StringBuffer line = new StringBuffer();
int contatore_index_parola = 1;
while ((parola = bufferedReader.readLine()) != null) {
if (map.containsKey(parola) && !parola.isEmpty()) {
line.append(contatore_index_parola + ":" + map.get(parola).intValue() + " ");
map.remove(parola);
}
contatore_index_parola++;
}
if (! line.toString().isEmpty()) {
fileWriter.append(getCategoryID(categoria) + " " + line + "\n"); // print riga completa documento N x1:y x2:a ...
}
} else { System.err.println("Dictionary file not found."); }
bufferedReader.close();
fileReader.close();
fileWriter.close();
} catch (IOException e) { return false;}
catch (NullPointerException ex ) { return false;}
finally {
try {
fileReader.close();
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
But the error still comes. ( it is thrown at:)
try {
File cat_out = new File("files/" + categoria + ".txt");
fileWriter = new FileWriter(cat_out, true);
} catch (IOException e) {
e.printStackTrace();
}
Thank you.
EDIT: SOLVED
I found the solution, there was, in the main function in which writeOccurencesFile is called, another function that create a RandomAccessFile and doesn't close it.
The debugger sais that Exception has thrown in writeOccurencesFile but using Java Leak Detector i found out that the pdf were already opened and not close after parsing to pure text.
Thank you!
Try using this utility specifically designed for the purpose.
This Java agent is a utility that keeps track of where/when/who opened files in your JVM. You can have the agent trace these operations to find out about the access pattern or handle leaks, and dump the list of currently open files and where/when/who opened them.
When the exception occurs, this agent will dump the list, allowing you to find out where a large number of file descriptors are in use.
i have tried using try-with resources; but the problem remains.
Also running in system macos built-in console print out a FileNotFound exception at the line of FileWriter fileWriter = ...
static boolean writeOccurencesFile(String WORDLIST,String categoria, TreeMap<String,Integer> map) {
File dizionario = new File(WORDLIST);
try (FileWriter fileWriter = new FileWriter( "files/" + categoria + ".txt" , true)) {
try (FileReader fileReader = new FileReader(dizionario)) {
try (BufferedReader bufferedReader = new BufferedReader(fileReader)) {
if (dizionario.exists()) {
StringBuffer stringBuffer = new StringBuffer();
String parola;
StringBuffer line = new StringBuffer();
int contatore_index_parola = 1;
while ((parola = bufferedReader.readLine()) != null) {
if (map.containsKey(parola) && !parola.isEmpty()) {
line.append(contatore_index_parola + ":" + map.get(parola).intValue() + " ");
map.remove(parola);
}
contatore_index_parola++;
}
if (!line.toString().isEmpty()) {
fileWriter.append(getCategoryID(categoria) + " " + line + "\n"); // print riga completa documento N x1:y x2:a ...
}
} else {
System.err.println("Dictionary file not found.");
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
This is the code that i am using now, although the bad managing of Exception, why the files seem to be not closed?
Now i am making a test with File Leak Detector
Maybe your code raises another exception that you are not handling. Try add catch (Exception e) before finally block
You also can move BufferedReader declaration out the try and close it in finally
How do I deserialize multiple objects from a file? Following is code that I have tried which works fine for one object but not for multiple objects.
public List<Show> populateDataFromFile(String fileName) {
// TODO Auto-generated method stub
Show s = null;
//FileInputStream fileIn=null;
try
{
FileInputStream fileIn=new FileInputStream("C:\\Users\\Admin\\Desktop\\Participant_Workspace\\Q1\\ShowBookingSystem\\ShowDetails.ser");
int i=0;
while((i=fileIn.read())!=-1){
// fileIn = new FileInputStream("C:\\Users\\Admin\\Desktop\\Participant_Workspace\\Q1\\ShowBookingSystem\\ShowDetails.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
s = (Show) in.readObject();
in.close();
fileIn.close();
System.out.println("Name: " + s.getShowName());
System.out.println("Show Time: " + s.getShowTime());
System.out.println("Seats Available: " + s.getSeatsAvailable());
}
}catch(IOException i)
{
i.printStackTrace();
}catch(ClassNotFoundException c)
{
System.out.println("Employee class not found");
c.printStackTrace();
}
return null;
}
I even tried using
while((i=fin.read())!=-1)
but it did not work. What change do I need to make?
Try this way:
Show s = null;
try {
FileInputStream fileIn = new FileInputStream(".....");
ObjectInputStream in = new ObjectInputStream(fileIn);
while (true) {
try {
s = (Show) in.readObject();
} catch (IOException ex) {
break;
} catch (ClassNotFoundException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Name: " + s.getShowName());
System.out.println("Show Time: " + s.getShowTime());
System.out.println("Seats Available: " + s.getSeatsAvailable());
}
in.close();
fileIn.close();
Below is a short working example. You will need to remove the ObjectInputStream in = new ObjectInputStream(fileIn); from outside the while loop as well.
FileInputStream fis = new FileInputStream("...");
ObjectInputStream ois = new ObjectInputStream(fis); //<- Outside the while loop.
try
{
while(true)
{
Student std = (Student)ois.readObject();
System.out.println(std.getName());
System.out.println(std.getAge());
}
}
catch(IOException e)
{
e.printStackTrace(); //This exception will be thrown if the End Of File (EOF) is reached.
//
}
finally
{
fis.close(); //<- Outside the while loop.
ois.close(); //<- Outside the while loop.
}
In this case the solution is:
to put all objects in a list
serialize the list
This way you only have one object to de-serialize: the list. (As a bonus you get your object in a nicely organised (or not!) list).
If you have multiples type of object to serialize, serialize them in a list per class. Each list in a different file.
I am trying to serialize an object array and write it to a file named address.ser and then read back from the file, deserialize the object array and display its attributes. I tried serializing the whole arrayList at once(deserializing it in a single session while reading) and also tried serializing each object of the object array one by one(deserializing it one by one while reading). The problem is, while reading back from the address.ser file I am getting data only of the last object which was written and none other.
Here is the code snippet:
Employee[] a=new Employee[5];
List<Employee> arr=new ArrayList<Employee>();
for(int i=0;i<=4;i++)
{
a[i]=new Employee();
System.out.println("Enter name,age,height,weight,house_no:");
a[i].name=sc.next();
a[i].age=sc.nextInt();
a[i].height=sc.nextDouble();
a[i].weight=sc.nextDouble();
a[i].house_no=sc.nextInt();
arr.add(a[i]);
}
This is the code snippet for writing objects to address.ser:
for(int i=0;i<=4;i++)
{
try
{
fout = new FileOutputStream("e:\\address.ser");
oos = new ObjectOutputStream(fout);
oos.writeObject(a[i]);
//oos.writeChars("\n");
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
oos.close();
fout.close();
}
}
This is the code snippet for reading objects from address.ser:
List<Employee> recordList=new ArrayList<Employee>();
for(int i=0;i<=4;i++)
{
try
{
file = new FileInputStream("e:\\address.ser");
input = new ObjectInputStream (file);
//deserialize the List
Employee readCase=(Employee) input.readObject();
recordList.add(readCase);
System.out.print("Employee "+i+" ");
System.out.print((recordList.get(i).name)+" ");
System.out.print((recordList.get(i).age)+" ");
System.out.print((recordList.get(i).height)+" ");
System.out.print((recordList.get(i).weight)+" ");
System.out.print((recordList.get(i).house_no)+" ");
System.out.println();
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
file.close();
input.close();
}
}
The final output being:
This is the way to do,
public class Test {
public static void main(String[] args) {
Employee employee=new Employee("jhon");
Employee employee2=new Employee("jojo");
Employee employee3=new Employee("albin");
ArrayList<Employee> list=new ArrayList<Employee>();
list.add(employee);
list.add(employee2);
list.add(employee3);
try {
FileOutputStream outputStream=new FileOutputStream("add.ser");
ObjectOutputStream objectOutputStream= new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(list);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
FileInputStream inputStream=new FileInputStream("add.ser");
ObjectInputStream objectInputStream =new ObjectInputStream(inputStream);
ArrayList<Employee> list2=(ArrayList<Employee>) objectInputStream.readObject();
for (Employee employee4 : list2) {
System.out.println(employee4.getName());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
The problem is you are trying to write the object in a wrong way. You are writing each element of the ArrayList in a same file. So what is happening is a new element is replacing the old one. So write the whole List at a time liek
oos.writeObject(yourList);
Corrected Solution
You're overwriting the file for each element you attempt to serialize. Therefore, the last serialized element remains. A file of serialized data has a header, so you must write your data in one shot.
fout = new FileOutputStream("e:\\address.ser");
oos = new ObjectOutputStream(fout);
for(int i=0;i<=4;i++)
{
try
{
oos.writeObject(a[i]);
}catch(Exception e){}
}
However, it's more efficient to serialize the entire list in one shot.
I have to implement Object Files for a java project, however I am having trouble when it comes to loading the file (Save is all OK)
public static void loadStudentList() {
boolean endOfFile = false;
try {
// create a FileInputStream object, studentFile
FileInputStream studentFile = new FileInputStream("Students.obf");
// create am ObjectImnputStream object to wrap around studentStream
ObjectInputStream studentStream = new ObjectInputStream(studentFile) ;
// read the first (whole) object with the readObject method
Student tempStudent = (Student) studentStream.readObject();
while (endOfFile != true) {
try {
tempStudent = (Student) studentStream.readObject();
stud1.add(tempStudent);
}
catch(EOFException e) {
endOfFile = true;
}
}
studentStream.close();
//use the fact that the readObject throws an EOFException to check whether the end of eth file has been reached
}
catch(FileNotFoundException e) {
System.out.println("File not found");
}
catch(ClassNotFoundException e) { // thrown by readObject
/* which indicates that the object just read does not correspond to any class
known to the program */
System.out.println("Trying to read an object of an unkonown class");
}
catch(StreamCorruptedException e) { //thrown by constructor
// which indicates that the input stream given to it was not produced by an ObjectOutputStream object
System.out.println("Unreadable File Format");
}
catch(IOException e) {
System.out.println("There was a problem reading the file");
}
}
This is the code I used to load the files. The program will load ONLY the last 2 records in my file. The Idea is that I load all of them to an array list for future use in the program. Also I am not getting any of my catches back. Any help? Thanks :)
You never add to the list the first Student that you read
Student tempStudent = (Student) studentStream.readObject();
while (endOfFile != true)
{
try
{
tempStudent = (Student) studentStream.readObject();
stud1.add(tempStudent);
}
Remove the read before the while, like the code below
while (endOfFile != true)
{
try
{
Student tempStudent = (Student) studentStream.readObject();
stud1.add(tempStudent);
}
I am not sure if this will solve your problem
Why don't you add the objects to an ArrayList<Type> then write/serialize them to file
and then for reading/deserialize it, read the data into one ArrayList<Type>.
Then you could fetch your objects one by one from the ArrayList
This might be an easier trouble free way of doing it.
//Serialize
ArrayList<Student> students = new ArrayList<Student>();
//Add the student objects to the array list
File f = new File("FileName.ser");
ObjectOutputStream objOut = new ObjectOutputStream(new FileOutputStream(f));
objOut.writeObject(students);
//Deserialize
ArrayList<Student> students = new ArrayList<Student>();
ObjectInputStream objIn = new ObjectInputStream(new FileInputStream(new File("FileName.ser")));
students = (ArrayList<String>) objIn.readObject();