2

This is my first file

   public class ObjectStream 
     {
       public static void main(String args[]) throws FileNotFoundException, IOException
     {
     java.io.File f=new java.io.File("D:Employee.outt") ;  
      Employee e=new Employee("John");
      Employee e1=new Employee("Mary");
         Employee e2=new Employee("Christian");
       OutputStream os=new java.io.FileOutputStream(f);

       java.io.ObjectOutputStream oos=  new ObjectOutputStream(os);
      oos.writeObject(e);
       oos.writeObject(e1);
         oos.writeObject(e2);
      }
      }

This is my second file

    public class Employee implements java.io.Serializable
    {
     private static int count=100;
    private int eid;
     private String ename;

     public Employee()
    {
     count++;
     this.eid=count;        
    }

    public Employee(String ename)
   {
    this();
    this.ename=ename;        
    }

    public static int getCount() {
       return count;
     }

    public static void setCount(int count) {
      Employee.count = count;
     }

     public int getEid() {
      return eid;
      }

    public void setEid(int eid) {
      this.eid = eid;
    }

    public String getEname() {
      return ename;
     }

     public void setEname(String ename) {
         this.ename = ename;
   }

   }

This is my third file

      public class MainClass
    {
         public static void main(String args[]) throws FileNotFoundException,        IOException, ClassNotFoundException
       {
        File f=new File("D:Employee.outt");
       byte data[]=new byte[(int)f.length()];
    InputStream is=new java.io.FileInputStream(f);
      java.io.ObjectInputStream ois=new java.io.ObjectInputStream(is);
    Object o=ois.readObject();



    while(o!=null)
         {
   Employee e=(Employee)o;
   System.out.println(e.getEid());
   System.out.println(e.getEname());
     o=ois.readObject();
       }


    ois.close();
    is.close();
     }
     }

I am trying to read objects stored in Employee.outt in via this third file but it is reading all the objects but at the end throwing

Exception in thread "main" java.io.EOFException.

I don't know how to resolve it.

tshepang
  • 12,111
  • 21
  • 91
  • 136
TruePS
  • 493
  • 2
  • 12
  • 33
  • Have you verified file path & name? Shouldn't it be `D:\\Employee.outt` ? – Shishir Kumar Mar 28 '14 at 05:51
  • @Shishir Yes I have It is reading file,there is no problem in reading file but at the end of file it is giving EOF exception. – TruePS Mar 28 '14 at 05:53
  • possible duplicate of [EOFException when reading files with ObjectInputStream](http://stackoverflow.com/questions/12684072/eofexception-when-reading-files-with-objectinputstream) – Shishir Kumar Mar 28 '14 at 06:23

3 Answers3

2
while(o!=null)

This isn't a valid way to read an ObjectInputStream. The readObject() method only returns a null if you wrote a null. At end of stream it throws, guess what, an EOFException, so the correct way to read the stream is to loop calling `readObject() until you catch that exception, then break and close the stream.

at the end of file it is giving EOF exception

That's exactly what EOFException means.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • but my friend run the same program by doing the same thing.I just don't wanna catch the exception I just wanna know when object reaches End of stream and close my loop just like in Filereader when EOF has reached it returns -1 and we close our loop. – TruePS Mar 28 '14 at 06:11
  • 1
    You can also first send the length of how many objects will be transferred, then you can stop reading based on that. – centic Mar 28 '14 at 06:14
  • 1
    You don't have any choice. That's how the API works. It throws `EOFException:` you have to catch it. And you can't rely on information in the file as suggested by @centic: premature end of file can still happen in the real world, and you still have to deal with it correctly. – user207421 Mar 28 '14 at 06:16
  • @centic How can I know the length of objects if I am reading say a random file. – TruePS Mar 28 '14 at 06:19
  • @EJP Can you explain "premature end of file can still happen in the real world, and you still have to deal with it correctly".How? – TruePS Mar 28 '14 at 06:21
  • 1
    @TruePS You aren't reading a random file. You are reading an `ObjectInputStream.` If something went wrong writing the file between writing the count and writing the last object, there will be fewer objects in the file than indicated by the count. You cannot rule this out. Disk errors and process interruptions do happen. – user207421 Mar 28 '14 at 06:21
  • 1
    @TruePS, your sample looked like you'd know, if not I think you'll need to expect and handle the exception, also available() is not useful as on the stream it is documented to only return the number of bytes that can be read without blocking, not the overall number of bytes left to read. – centic Mar 28 '14 at 06:31
  • @centic yeah available is not an alternative man.I guess I have to use try and catch block then.Could you plz take a look at this also http://stackoverflow.com/questions/22659969/paramvalues-not-working-in-jstl-and-throwing-an-exception – TruePS Mar 28 '14 at 06:35
  • @EJP yeah I also read your comments on another article regarding EOF exception.With reputaion points you are having I don't think you can be wrong in any case.So Now I believe that I have to use try and catch block.Also if you could plz take a look at this http://stackoverflow.com/questions/22659969/paramvalues-not-working-in-jstl-and-throwing-an-exception. – TruePS Mar 28 '14 at 06:38
  • Of course I can be wrong, but I'm not wrong about this ;-) – user207421 Mar 28 '14 at 06:59
1

You should close ObjectOutputStreamin ObjectStream class.

oos.writeObject(e);
oos.writeObject(e1);
oos.writeObject(e2);

oos.close();

In the MainClass you can use a try-finally block to close the inputstream.

try
{   
  InputStream is=new java.io.FileInputStream(f);
  java.io.ObjectInputStream ois=new java.io.ObjectInputStream(is);    

    // READ logic here   
}
finally
{    
 ois.close();
 is.close();  
}
r3ap3r
  • 2,775
  • 2
  • 17
  • 16
  • No it gives stream closed error because I am reading 3 objects in loop. – TruePS Mar 28 '14 at 06:01
  • 1
    @TruePS No it doesn't, unless you put the close into the read loop, which isn't what he suggests here. He is certainly correct to say you should close the stream when you've finished writing it, but it doesn't resolve your actual question. – user207421 Mar 28 '14 at 06:09
  • @EJP I haven't finished reading the stream so How can I close the stream before reading the whole stream.If I wanna read 100 objects then if I close the stream in the loop.How would I be able to read other 99 objects. – TruePS Mar 28 '14 at 06:13
  • 1
    @TruePS you should close the *outputstream* when it finishes writing into the file. It has nothing to do with reading. – r3ap3r Mar 28 '14 at 06:15
  • 1
    @TruePS I'll say it again. Nobody has suggested you close the stream in the read loop. Obviously you can't close the stream in the read loop. Don't close the stream in the read loop. Please read what's written here more carefully. – user207421 Mar 28 '14 at 06:16
  • @r3ap3r Ok my bad I just got a little confused.I closed the stream while writing the file.But still while reading it gives EOF exception. – TruePS Mar 28 '14 at 06:18
  • 1
    @TruePS It will always give `EOFException.` You have to catch it. Just accept it. – user207421 Mar 28 '14 at 06:18
1
  1. You really should flush and close the object output stream in "first file".

  2. You only need to close 'ois' in "third file". The other stream is automatically closed for you.

  3. If you know how many objects you're going to write, change "first file" to write the number of objects following first, then change "third file" to read that number and only read that many objects. That way, you never get the EOF exception, because you stop reading when you've read the last object.

As EJP pointed out, you still have to catch the EOFException, because the file you're reading might be damaged.

In First File:

...
oos.writeInt(3);
oos.writeObject(e);
...

In Third File:

...
try {
  int numObjects = ois.readInt();
  for( int a = 0; a < numObjects; ++a ) {
      ...
  }
} catch( EOFException e ) {
    ...
}
EdwinW
  • 1,007
  • 2
  • 13
  • 32
  • 1
    You will 'never get the `EOFException`' unless something went wrong writing the file, which you cannot rule out in the real world, so you *will* get it, so you have to defensively code against it. – user207421 Mar 28 '14 at 06:19
  • 1
    Quite correct, you still need to trap the EOF Exception, but now it's truly an exception case, instead of an abuse. – EdwinW Mar 28 '14 at 06:22
  • 1
    I'm not interested in discussing views on exception handling. I'm only interested in discussing how to use this API which is already designed. – user207421 Mar 28 '14 at 06:23
  • @EdwinW After flushing and closing the output Stream in first file it still gives EOF exception.Secondly if let's say I wanna read a random file so How could I know in advance how many objects I have to read. – TruePS Mar 28 '14 at 06:24
  • 1
    I did say "if you know how many"... As a hacky alternative, I suppose you might try checking 'available()' to see if there's data still available to read. It's ugly though... – EdwinW Mar 28 '14 at 06:26
  • @EdwinW I hate to use try and catch block except in situations where I am bound to use it.I guess this is the situation where I am bound to use it.Thanks for your support man can you plz also have a look at this http://stackoverflow.com/questions/22659969/paramvalues-not-working-in-jstl-and-throwing-an-exception – TruePS Mar 28 '14 at 06:34