• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Bear Bibeault
  • Devaka Cooray
  • Liutauras Vilda
  • Jeanne Boyarsky
Sheriffs:
  • Knute Snortum
  • Junilu Lacar
  • paul wheaton
Saloon Keepers:
  • Ganesh Patekar
  • Frits Walraven
  • Tim Moores
  • Ron McLeod
  • Carey Brown
Bartenders:
  • Stephan van Hulst
  • salvin francis
  • Tim Holloway

How can I read all objects in a file with ObjectInputStream?  RSS feed

 
Ranch Hand
Posts: 59
Eclipse IDE Hibernate Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi people. I saw an example in Head First - Java that some objects are read from a file with ObjectInputStream. It's like this:


I need to do it in a loop (like for or while) because I don't now how many objects the file haves.
Is it possible? How can I do it?

Thanks.

Dadonas
 
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, welcome to the ranch!

Give it a try in a loop and see what happens when you try to read past the last object.

Hint: expect an exception. Note the exact exception class and look up the JavaDoc.

BTW: It is kind of the ranch style to give you some hints and set you off to experiment. The more you find on your own the more you will remember. Have fun, let us know what you find!
 
Danilo Dadonas
Ranch Hand
Posts: 59
Eclipse IDE Hibernate Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi friend Stan. Your hint was my first idea but I wanted a professional opinion. Below the solution:


Thanks for help me.
 
Stan James
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It looks from the doc that the library forces us to use try catch for normal expected logic. This is generally a pretty bad thing, but I don't see any other way. Anyone else?
 
Danilo Dadonas
Ranch Hand
Posts: 59
Eclipse IDE Hibernate Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stan, I think your hint is the unique way, but the class ObjectInputStream should have a method like hasNext(). Don't you think?
 
Bartender
Posts: 9550
12
Linux Mac OS X Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm not a fan of using exceptions to handle expected events, as is apparently the case with ObjectInputStream. What I usually do when faced with this situation is put all my objects in a collection and serialize the collection. Of course, with large numbers of objects this method could cause performance problems.
 
Danilo Dadonas
Ranch Hand
Posts: 59
Eclipse IDE Hibernate Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Accurately, Joe. That's it!!!

Thank you so much.

Dadonas
 
author and iconoclast
Posts: 24203
40
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Note that a stream is a stream, and you don't have to restrict your stream to holding just serialized objects. You could, for example, write the number of objects to follow as a four-byte int first (using DataOutputStream, for example.) Then read that word before trying to read any objects from the stream.
 
Stan James
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Neat! I suppose one could also put a delimiter or eof marker after each object if you don't know the number before you start writing.
 
Danilo Dadonas
Ranch Hand
Posts: 59
Eclipse IDE Hibernate Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yeah, all ideas are welcome, but in my case, serialize an array is the way. I'm serializing objects to a file then after insert them in Oracle in other desktop. I'm using DAO, then I have an Interface like the exemplo bellow:

http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html

I read the information from my Oracle, serialize the informatiion, send the file to the other desktop, unserialize the objects an insert in the other Oracle.
I know it's not the best way, but they want it.

One more time, very thanks.
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[Stan]: It looks from the doc that the library forces us to use try catch for normal expected logic. This is generally a pretty bad thing, but I don't see any other way. Anyone else?

I usually write and read an int first, as EFH suggests. Or write a Collection or array of objects at once. But if you don't have them all in memory at the start, or don't know in advance how many objects there will be, you could also do something like this:


[Joe]: What I usually do when faced with this situation is put all my objects in a collection and serialize the collection. Of course, with large numbers of objects this method could cause performance problems.

It could, but it's pretty much the same problem you'd have with any other technique suggested so far. The objects will all have to be in memory at once anyway, since the ObjectInputStream keeps a reference to everything it has deserialized so far. So there's no way you can save memory by processing one object and then discarding it, unless you close one stream and start a new one. Which adds more overhead in various forms. And the memory used by an ArrayList of objects, or an array of those same objects, is generally pretty close to the memory used by the objects themselves. I tried serializing 1000 Integer objects in various forms to see how much space they took:

ArrayList of Integers: 10125 bytes
Integer[] array: 10112 bytes
writeInt(1000) followed by 1000 Integers: 10077 bytes
1000 Integers followed by an EndOfStreamSignal: 10105 bytes

In the case of Integers I could have made it smaller by writing ints instead, but the point was to use a simple small object. For larger objects (or a larger number of objects, the type of container you use will matter even less (proportionately).

[EFH]: You could, for example, write the number of objects to follow as a four-byte int first (using DataOutputStream, for example.)

Minor clarification - an ObjectOutputStream implements DataOutput, an interface also implemented by DataOutputStream. As a result, an ObjectOutputStream already has a writeInt() method and many similar methods - there's no need to use a DataOutputStream also. Likewise ObjectInputStream has a readInt(), just like DataInputStream does. So writing and reading ints as EFH suggests is extremely easy.
 
Ranch Hand
Posts: 50
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

when i tried this below loop



times.add(..) gives nullpointer exception.
If i run //tim2 = (PersistentTime)in.readObject();

this line read the object in tim2 variable.

Also how while(true) loop will break?
i guess when it enters into exception,it should stop. But i have tried and its is running infinite times.
 
Ranch Hand
Posts: 228
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Use "break" inside the loop and first check weather readObject() returns null of not then add it into the List..

thanks
 
Bartender
Posts: 3321
86
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Ishan Pandya wrote:Use "break" inside the loop and first check weather readObject() returns null of not then add it into the List..


That is good practice but it's not why there is a NullPointerException, you can add nulls to an ArraylList. The problem is there is no ArrayList object only a variable of type ArrayList.

should be (including the generic notation)


@isha krishnan When you have a question please start your own thread, do not just append your question onto an old thread.
 
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am using the "fis.available() > 0" condition.

Is this a valid solution?
 
Bartender
Posts: 9494
184
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to CodeRanch Andrea!

I'm afraid not. InputStream.available() does not give a reliable file size. Instead, just loop until readObject() returns null.
 
Tony Docherty
Bartender
Posts: 3321
86
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No it's not a valid solution.

available() returns the number of bytes that can be read without blocking. If it returns 0 it does not mean the end of the stream has been reached it just means there are currently no more bytes available to read. This could be due to i/o delays, network delays etc.

Using available() in this way may appear to work every time when the file is stored locally but there are no guarantees. In short it's extremely bad practice to do this.
 
Andrea Lo
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you for your pointers about not using .available().
Using  CountingInputStream of Apache commons-io, I created a class CountingFileInputStream, which calls File.length() during construction and then provides a .remaining() method, which returns the number of bytes not yet read.
Would now using

be a valid solution?
I am asking out of curiosity, as the solution of using an EndOfStreamSignal class is valid for me.
 
Stephan van Hulst
Bartender
Posts: 9494
184
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Why would you want to do this and not the regular solution?
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!