Understanding flow of object creation - java

I'm new to java and I wonder if there is simple way to know flow like the following of object creation, I'm using eclipse and when I write new ObjectInputStream and press CTRL+SPACE.
I don't see any option that I can enter new BufferedInputStream (I have copied the code from example) and than to create new object for FileInputStream etc.
in = new ObjectInputStream(new BufferedInputStream(new FileInputStream("emp.dat")));
List temp = (List)in.readObject();
I give that example since this is the first time that I saw this kind of creation new object flow and I want to use some best practice for the next times.

This is a classic example of using [Decorator Pattern][1]. You will wrap objects to add behavior.

This is very simple. This is equivalent to :
FileInputStream fis = new FileInputStream("emp.dat");
BufferedInputStream bis = new BufferedInputStream(fis)
ObjectInputStream in = new ObjectInputStream(bis);
As you are new to Java, you should check javadocs instead of checking it in Eclipse.
Check : FileInputStream, BufferedInputStream, ObjectInputStream

Ctrl+Space shows you options you have available at that point to get the options you might value if you created something you have to type new and then Ctrl+Space
BTW: ObjectInputStream and ObjectOutputStream are already buffered so adding more buffering isn't best practice IMHO.

Related

using FileInputStream and FileOutputStream

Hi I had a couple of questions about using the FileInputStream and FileOutputStream classes.
How would FileInputStream objects locate a file it is trying to read in?
Where would FileOutputStream save a file to?
Thanks.
Strange question and I will give a strange answer.
First part: don't use either, use Files:
final Path src = Paths.get("some/file/somewhere");
final InputStream in = Files.newInputStream(src);
// ...
final Path dst = Paths.get("another/file");
final OutputStream out = Files.newOutputStream(dst);
Note that Path objects are in essence abstract: nothing guarantees that they point to a valid entry. If they don't, the Files methods above will throw a NoSuchFileException (file does not exist), or an AccessDeniedException (sorry mate, you can't do that), or any relevant exception.
Second part: File*Stream
The basics are the same: if you are stuck with Java 6 you have to use File instead of Path, but File is as abstract as Path is; it may, or may not, point to a valid location.
When you issue:
final String dst = "/some/file";
new FileOutputStream(dst);
internally, FileOutputStream will create a File object; which means the above is equivalent to:
final String dst = "/some/file";
final File f = new File(dst);
new FileOutputStream(f);
Conclusion: no, File*Stream does not know per se whether a file exists as long as it does not try to open it. Paths as well as Files are completely abstract until you try and do something with them.
And do yourself a favour: use the new file API which Java 7+ provides. Have you ever tried to initiate a FileInputStream with a File which exists but you cannot read from? FileNotFoundException. Meh. Files.newInputStream() will at least throw a meaningful exception...
Generally, you simply pass the file object to the stream instantiations.
FileInputStream is = new FileInputStream(f);
FileOutputStream os = new FileOutputStream(f);
BufferedInputStream is2 = new BufferedInputStream(is);
BufferedOutputStream os2 = new BufferedOutputStream(os);
Also consider using Printwriter for the output stream when you are working with text files.
About Streams:
Streams are objects that allow an app to communicate with other programs.
To directly answer your question, in Java, here is how I would use the Streams.
//You need to import a few classes before you begin
import java.io.FileInputStream;
import java.io.FileOutputStream;
You can declare them this way
FileInputStream is = new FileInputStream("filename.txt"); //this file should be located within the project folder
For output stream, it can be accessed a similar way:
FileOutputStream os = new FileOutputStream("filename.txt"); //this file should be located within the project folder
More Information:
I recommend using a PrintWriter when trying to write to text files. To do this, you would implement the following:
import java.io.PrintWriter;
Then use this to write to the file:
PrintWriter pw = new PrintWriter(OUTPUT_STREAM);
I also recommend using the Scanner class when reading in user data:
import java.util.Scanner;
Then use this to read the input:
Scanner kb = new Scanner(INPUT_STREAM); //now you can access this data by using methods such as nextInt, nextDouble, etc...

ObjectInputStream Handling classNotFoundException

I have an issue while reading the data from a file using objectInputStream. Please find the code below
File file = new File("model.pst")
if (file.exists()) {
fis = new FileInputStream(file);
in = new ObjectInputStream(fis);
input = (List<GlobalModel>) in.readObject();
in.close();
}
I got to know from the ObjectOutputStream http://docs.oracle.com/javase/6/docs/api/java/io/ObjectOutputStream.html docs, that while writing the object to the file, he default serialization mechanism for an object writes the class of the object, the class signature, and the values of all non-transient and non-static fields.I have an issue where the class name has been changed after writing the object to the file and when I use the above code to read the values, its throwing a classNotFound exception. I would like to know if there is a way, I can handle this exception, i.e once it comes to the exception block, can I replace the classname in the object that is being read to the new class name and make it work ?
Please Assist. Thanks in Advance
I've never done this myself but it should be possible to replace a class by another by making a subclass of object input stream and overriding the resolveClass method, http://docs.oracle.com/javase/6/docs/api/java/io/ObjectInputStream.html#resolveClass(java.io.ObjectStreamClass)

Write with ObjectOutputStream into multiple ZipEntrys in a single ZipOutputStream

I want to create a zip archive in Java where each contained file is produced by serializing some objects. I have a problem with correctly closing the streams.
The code looks like this:
try (OutputStream os = new FileOutputStream(file);
ZipOutputStream zos = new ZipOutputStream(os);) {
ZipEntry ze;
ObjectOutputStream oos;
ze = new ZipEntry("file1");
zos.putNextEntry(ze); // start first file in zip archive
oos = new ObjectOutputStream(zos);
oos.writeObject(obj1a);
oos.writeObject(obj1b);
// I want to close oos here without closing zos
zos.closeEntry(); // end first file in zip archive
ze = new ZipEntry("file2");
zos.putNextEntry(ze); // start second file in zip archive
oos = new ObjectOutputStream(zos);
oos.writeObject(obj2a);
oos.writeObject(obj2b);
// And here again
zos.closeEntry(); // end second file in zip archive
}
I know of course that I should close each stream after finishing using it, so I should close the ObjectOutputStreams in the indicated positions. However, closing the ObjectOutputStreams would also close the ZipOutputStream that I still need.
I do not want to omit the call to ObjectOutputStream.close() because I do not want to rely on the fact that it currently does not more than flush() and reset().
I also cannot use a single ObjectOutputStream instance because then I miss the stream header that is written by the constructor (each single file in the zip archive would not be a full object serialization file, and I could not de-serialize them independently).
The same problem occurs when reading the file again.
The only way I see would be to wrap the ZipOutputStream in some kind of "CloseProtectionOutputStream" that would forward all methods except close() before giving it to the ObjectOutputStream. However, this seems rather hacky and I wonder if I missed a nicer solution in the API.
If your OutputStream wrapper throws an exception when closed more than once, it is not a hack. You can create a wrapper for each zip entry.
From an architectural point of view, I think the ObjectOutputStream author should have provided an option to disable close() cascading. You are just workarounding his lacking API.
In this case, and for all the reasons you mentioned, I would simply not pipe my ObjectOutputStream to the ZipOutputStream. Instead, serialize to a byte[] and then write that straight into the ZipOutputStream. This way, you are free to close the ObjectOutputStream and each byte[] you produce will have the proper header from the serializer. One down side is you wind up with a byte[] in memory that you didn't have before but if you get rid of it right away, assuming we're not talking about millions of objects, the garbage collector shouldn't have a hard time cleaning up.
Just my two cents...
It at least sounds less hacky than a stream subclass that changes the close() behavior.
If you're intending to throw the ObjectOutputStream away anyway, then it should be sufficient to call flush() rather than close(), but as you say in the question the safest approach is probably to use a wrapper around the underlying ZipOutputStream that blocks the close() call. Apache commons-io has CloseShieldOutputStream for this purpose.

How close Java Input Streams?

In the following code:
DataInputStream in = new DataInputStream(
new BufferedInputStream(new FileInputStream(file)));
in.close();
Do I need to close the 2 other stream in addition to closing the "top level" stream?
if you look the source of DataInputStream you can see that it closes the underlying streams as well. so you don't need. and this is (or should be) true for all type of streams.
I will use this opportunity to answer with an answer I have already made before.
By using Project Lombok you can let Lombok correctly close the streams for you.
Details can be found here.
Karazi, is right in suggesting that. Further, just to get an idea and a little more insight, Java IO API is actually implemented using decorator pattern. You can check out decorator pattern on wiki.
I'd stick the close in a finally block just to make sure it is flushed properly in case of an exception.
public void tryToDoWhatever() throws Exception
{
DataInputStream in = null;
try
{
in = new DataInputStream(
new BufferedInputStream(new FileInputStream(file)));
}
finally
{
if (in != null)
in.close();
}
}

how to do Serializtionf of a file

i have a xml file named as default xml with sample contents as
<check>hi</check>
in my application i am doing an operation such that it wil operate on the xml and writes the new value to it, by overriding the newvalue on the oldone
ex:
<check>hi updated</check>
and i closed my application now
my problem is here:
whenever i start application again i should get the contents of default xml as
<check>hi<check>
instead of
<check>hi updated</check>
how can i achieve this ,can i have an steps to implement this r any sample code to implement this
i wil b thankful to ur valuable replies
Um... don't overwrite the file then? Keep the changes in memory or work on a temporary copy.
Writing data:
FileOutputStream os = new FileOutputStream("C:/cust.xml");
XMLEncoder encoder = new XMLEncoder(os);
Person p = new Person();
p.setFirstName("John");
encoder.writeObject(p);
encoder.close();
Reading data:
FileInputStream os = new FileInputStream("C:/cust.xml");
XMLDecoder decoder = new XMLDecoder(os);
Person p = (Person)decoder.readObject();
decoder.close();
EDIT: You can also use XStream library. Here will you find a complete tutorial about it

Categories

Resources