OK, so I want to thank all of you that helped me with my little problems within the past few days,I have almost come to the end of this project thanks to your suggestions. Now the thing is, I used ObjectInputStream & ObjectOutputStream to write down whole objects to a textual file and later read from the file, and it works perfectly, but it only shows me the latest entries. That is, when I write an object to the file,then terminate the program, and later start another program that reads from that file, I only get the object that I wrote the last time, not the ones I wrote down in the previous attempts. So I do not know if the problem is in my code logic, or am I misusing the ObjectInputStream & ObjectOutputStream methods? Will you please take a look at my code snippet? Thanks a lot,regards.

This "result" object is an instance of the Result class, a class that I created in order to store the results from the voting as integers, then write them to this object and then write the object to the file. This "addBand()" method takes the variables that represent the results, then just stores them in its own fields, and I write the whole object down.

result.addBand(zepp, stones, floyd, purple, acDc);

ObjectOutputStream stream = new ObjectOutputStream(new FileOutputStream("votingResults.txt"));
				stream.writeObject(result);
				stream.close();

Then I have this method for reading from the file. Anyway, I assume that the following code is OK, since it does read correctly. I assume that I've made a mistake in writing to the file, since it never gets bigger - it's only 1KB always!

public void readStream(){
		ObjectInputStream inputStream = null;
		try{
			inputStream = new ObjectInputStream(new FileInputStream("votingResults.txt"));
			Object obj = null;
			
			while(!(obj = inputStream.readObject()).equals(null)){
				if(obj instanceof Result){
					System.out.println(((Result)obj).toString());
				}
			}
			inputStream.close();
			
		}catch(EOFException eof){
			System.out.println("End of file reached");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

Recommended Answers

All 26 Replies

I just checked - it is the same with the regular files. I wrote a string to a file,then started the program again with a different string, and it just overwrote the previous one... So how do I write additional lines,and keep the previous ones there? Thanks

Yes, open an output file and it overwrites the previous.
Try opening the fileoutput stream in append mode, eg
new FileOutputStream(fileName, true)

Oh I see it now. But I still get the error when trying to read from the ObjectINputStream. I modified this line, just added the second parameter - "true" -

ObjectOutputStream stream = new ObjectOutputStream(new FileOutputStream("votingResults.txt",true));

So now I suppose the program just appends the new objects to the previous ones,so I get this error when trying to read from the file.

java.io.StreamCorruptedException: invalid type code: AC
	at java.io.ObjectInputStream.readObject0(Unknown Source)
	at java.io.ObjectInputStream.readObject(Unknown Source)
	at server.Server.readStream(Server.java:368)
	at server.Server.main(Server.java:394)

Does this mean I should write some separator between the objects, e.g. write down a string that will separate them... But that will only complicate the reading process, and I thought the ObjectInputstream is capable of reading appended objects. I am totally confused with this one.

Written objects are not the same as text. I'm not sure you can append to a file containing an object. This will take further study.

You can definitely read multiple Objects from the same stream. Maybe worth checking that the output stream is properly flushed & closed after each session? I did see somewhere that there can be block-size padding issues in append mode, where some padding is left after the first write and the input stream gets confused, but I'm not sure what/when that was.
If that still doesn't work then put all you objects into some kind of Collection (eg ArrayList) and write the whole list (as a single Object) to a (non append) file. Then in each session you can read the while collection, add any new ones, write it all out again. A but tacky, yes, but depending on the volume may be plenty good enough.

Here's my test case. I was unable to append objects to a closed file.

// Test if you can write appending more than one object to a file
// Current results: you can not.

import java.io.*;
import java.awt.*; 
import java.util.*;   

public class WriteSerializedTesting {

	public static void main(String[] args) {
        final String fn = "WriteSerializedTesting.ser";   // This is the file we'll write to
        final int MaxWrites = 3;       // number of objects to write to the file

        File oldFile = new File(fn);
        oldFile.delete();  // get rid of old one

        for(int i=1; i <= MaxWrites; i++) {     // one based for min array size in test class
           try {
               // Write a class out
               FileOutputStream f = new FileOutputStream(fn, true);  // append to last one
               ObjectOutput out = new ObjectOutputStream(f);
   
               WriteSerializedData wst = new WriteSerializedData(i);
               out.writeObject(wst);
               out.flush();       // flush and close after each writing
               out.close();       
               System.out.println(i + " Wrote fn=" + fn + ", date=" + wst.date + ", aStr=" + wst.aStr[0]);
           }catch(Exception ex) {
               ex.printStackTrace();
           }
        } // end for(i)


        // Now try to read in what was written and appended
        try {
            FileInputStream f0 = new FileInputStream(fn);
            ObjectInputStream oin = new ObjectInputStream(f0);

           for(int i=1; i <= MaxWrites; i++) {
               WriteSerializedData wsd  = (WriteSerializedData)oin.readObject();
               System.out.println(i + " Read date=" + wsd.date + ", aStr=" + wsd.aStr[0]);
           }
           oin.close();
        }catch(Exception ex) {
            ex.printStackTrace();
        }

        System.exit(0);                 // Done
	} // end main()

   // A class to write  ---------------------------------
   static class WriteSerializedData implements Serializable {
     Date date = new Date();
     String[] aStr;

     public WriteSerializedData(int len) {
       aStr = new String[len];    // build unique data for each object
       for(int i=0; i < len; i++) {
           aStr[i] =  ""+ i;
       } // end for(i)
     }
   } // end class
} // end class

/* Output:

1 Wrote fn=WriteSerializedTesting.ser, date=Thu Sep 09 10:23:04 CDT 2010, aStr=0
2 Wrote fn=WriteSerializedTesting.ser, date=Thu Sep 09 10:23:04 CDT 2010, aStr=0
3 Wrote fn=WriteSerializedTesting.ser, date=Thu Sep 09 10:23:04 CDT 2010, aStr=0
1 Read date=Thu Sep 09 10:23:04 CDT 2010, aStr=0
java.io.StreamCorruptedException
	at java.io.ObjectInputStream.readObject0(Unknown Source)
	at java.io.ObjectInputStream.readObject(Unknown Source)
	at WriteSerializedTesting.main(WriteSerializedTesting.java:40)

*/

Did a bit more scratching a round, and found what seems to be the answer. Object I/O writes a header to the stream, so it's OK then to write multiple objects, but if you close & re-open the stream in append mode the next write writes a new header at the append point where input is not expecting it - so it won't work.
The ArrayList approach should be OK tho.

Well thanks NormR1 - I studied your code just to get to know a little more about this stuff, and thanks to JamesCherrill for the useful suggestion about the list. But it seems that id still doesn't work for me... I edited my code in the following manner and I get an exception: writing -

this.results = new LinkedList<Result>();
				this.results.add(result);
				ObjectOutputStream stream = new ObjectOutputStream(new FileOutputStream("votingResults.txt"));
				stream.writeObject(results);
				stream.close();

and reading -

public void readStream(){
		ObjectInputStream inputStream = null;
		try{
			inputStream = new ObjectInputStream(new FileInputStream("votingResults.txt"));
			Object obj = null;
			
			while(!(obj = inputStream.readObject()).equals(null)){
				if(obj instanceof LinkedList){
					for(int i = 0; i < results.size(); i++){
						System.out.println(((Result)results.get(i)).toString());
						
					}
					//System.out.println(((Result)obj).toString());
				}
			}
			inputStream.close();
			
		}catch(EOFException eof){
			System.out.println("End of file reached");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

I get a NullPointerException at this line -

for(int i = 0; i < results.size(); i++){

and it seems weird to me since I used the list's add() method to add the Result object,and it is still null. I'm sure it goes into that part of the code - the adding part,since it's a switch() case, and I choose that case. Have no bloody idea what the problem is this time...

Please copy and paste here the full text of the error messages

For the NPE, what variable is null? Why is it null? Backtrack in your code to see why.

(obj = inputStream.readObject()).equals(null))

I'm not sure if this test will do what you want.
to test if obj is null use: obj == null

Exception in thread "main" java.lang.NullPointerException
	at server.Server.readStream(Server.java:370)
	at server.Server.main(Server.java:399)

line 370 is

for(int i = 0; i < results.size(); i++){

and the other one is the method call in main(). So as I said - it complains about the LinkedList results being null, at it probably is not since i add objects to it. It may be that I do something wrong with this ObjectInput/OutputStream stuff. I'm a little overwhelmed these days, so I may be doing stupid mistakes. Can you see something wrong in the writing piece of code?

complains about the LinkedList results being null, at it probably is

What are you trying to do with a null object? Why are you calling a method for a null object?
As I said before, look at your code and see why that variable is null.
Where do you assign it a value? Do you call the code that gives it a value?
If you are not sure if it is called, add a print out there to show if the code is being executed. If it is not, check your logic to see why not.

Yeah, I tried that - I printed out something and concluded that the particular piece of code gets executed, so objects are being added to the list. So it is not null. So the problem must be in my reading method, I must have made a mistake in the readStream() method, since I have an Object obj in there as well as a LinkedList object. I'm on it

I think the problem is in the incompatibility in my code, between the "obj" object and the "results" object. Would you please be kind to write this function about reading on your own, just ignore my code, assume you have a LinkedList written in a file using ObjectOutputStream and you need to read it and print it out using ObjectInputStream. So then we'll compare the both functions and find the mistake. Hope I'm not asking too much.

Could you write a small program (modify what I posted above) that compiles and executes to demonstrate your problem?

Perhaps I should use the "obj" length/size in the for loop, now I am using the class' variable's property.Cast it to a list type or something and check it's length.

Could you write a small program (modify what I posted above) that compiles and executes to demonstrate your problem?

Would it be OK if I posted the whole code here so you'll be able to try it on your own?

I managed to figure that one out, here's what I did:

public void readStream(){
		ObjectInputStream inputStream = null;
		try{
			inputStream = new ObjectInputStream(new FileInputStream("votingResults.txt"));
			Object obj = null;
			
			while((obj = inputStream.readObject())!= null ){
				if(obj instanceof LinkedList){
					for(int i = 0; i < 3; i++){
					
						System.out.println(((LinkedList<Result>)obj).toString());
						
					}
					//System.out.println(((Result)obj).toString());
				}
			}
			inputStream.close();
			
		}catch(EOFException eof){
			System.out.println("End of file reached");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

So the problem is in the for loop,since this is a temporary solution using a fixed value, I must find a way to make a permanent check based on obj's length property.

Can you cast obj to a LinkedList and then use that?
LinkedList llObj = (LinkedList)obj;

Norm's right. You write a single (complex) Object - a linked list. You read a single Object - a linked list, but you need to cast the Object you read to linked list.
There's no reason to read in a while loop, there's only one Object

ps: Use the enhanced for loop - much easier

for (Result r : results) {
   System.out.println(r);
}

Sorry, previous 2 posts taken together are ambiguous, and the toString is redundant in a print(...) because print(...) does that anyway.
This what I meant:

LinkedList<Result> results = (LinkedList<Result>) inputStream.readObject();
for (Result r : results) {
   System.out.println(r);
}

Sorry, previous 2 posts taken together are ambiguous, and the toString is redundant in a print(...) because print(...) does that anyway.
This what I meant:

LinkedList<Result> results = (LinkedList<Result>) inputStream.readObject();
for (Result r : results) {
   System.out.println(r);
}

Yeah I just tried that one, and I got jut the last input. Only one element of the list. Here's the writing part:

results = new LinkedList<Result>();
				results.add(result);
				//System.out.println("Just added to the list");
				ObjectOutputStream stream = new ObjectOutputStream(new FileOutputStream("votingResults.txt"));
				stream.writeObject(results);
				//System.out.println("Just wrote down");
				stream.close();

and reading:

inputStream = new ObjectInputStream(new FileInputStream("votingResults.txt"));
			//Object obj = null;
			
			//while((obj = inputStream.readObject())!= null ){
				//if(obj instanceof LinkedList){
			results = (LinkedList<Result>) inputStream.readObject();
			for(Result r : results){
				System.out.println(r);
			}
			
//					for(int i = 0; i < 3; i++){
//					
//						System.out.println(((LinkedList<Result>)obj).toString());
//						
//					}
					//System.out.println(((Result)obj).toString());
				//}
			//}
			inputStream.close();

Thanks a lot anyway, it's really kind of you to help me out like this. I'm trying to do the same, when I find a problem I think I can help with.

Line 1 you create a new list and add the latest to it, and write that, so yes, that's all you get.
You need to add the new Result to the existing list of previous results

String fileName = "votingResults.txt"
inputStream = new ObjectInputStream(new FileInputStream(fileName );
results = (LinkedList<Result>) inputStream.readObject();
inputStream.close();
// create new result here ....
results.add(result);
ObjectOutputStream stream = new ObjectOutputStream(new FileOutputStream(fileName ));
stream.writeObject(results);
stream.close();

Line 1 you create a new list and add the latest to it, and write that, so yes, that's all you get.
You need to add the new Result to the existing list of previous results

String fileName = "votingResults.txt"
inputStream = new ObjectInputStream(new FileInputStream(fileName );
results = (LinkedList<Result>) inputStream.readObject();
inputStream.close();
// create new result here ....
results.add(result);
ObjectOutputStream stream = new ObjectOutputStream(new FileOutputStream(fileName ));
stream.writeObject(results);
stream.close();

I understand, I did that and it's OK now. But I got other exceptions now - Connection reset,connection refused..., I'll try to work them out now.

Maybe time to mark this as solved and start a new thread for connection issues if required?

OK, I'll mark this as solved. I guess it's something with closing sockets/streams, I'll try to solve it myself first. Regards

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.