vanmarcke
vanmarcke

Reputation: 133

Use of PrintWriter with streams of bytes

I'am testing the PrintWriter class which can handle streams of characters and streams of bytes. Everything went smooth when i tried with streams of characters, now i was testing it with streams of bytes and whenever i print what it reads it always displays null(exception). Here's the code:

package com.files.ex1;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;

public class ex1 {
    public static void main(String[] args) {
        PrintWriter oPW;
        try {
            oPW = new PrintWriter(new ObjectOutputStream(new FileOutputStream("data.txt")));
            oPW.write("1\n");
            oPW.write("2\n");
            oPW.write("3\n");
            oPW.flush();
            oPW.close();
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }
}

This is the class that tries to read and always prints null:

package com.files.ex1;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class ex1_2 {
    public static void main(String[] args) {
        ObjectInputStream oOIS;
        try {
            oOIS = new ObjectInputStream(new FileInputStream("data.txt"));
            String s = (String) oOIS.readObject();
            System.out.println(s);
        } catch (IOException e) {
            System.out.println(e.getMessage());
        } catch (ClassNotFoundException e) {
            System.out.println(e.getMessage());
        }
    }    
}

Also what are the advantages of using this class? For streams of characters i can just use BuffedReadear or BufferedWriter to optimize reads or writes respectively, and it also has flush() method. And what is the advantage of using PrintWriter with streams of bytes? Using ObjectOutputStream alone works when i try to do the operations above.

Upvotes: 0

Views: 2657

Answers (1)

Samuel
Samuel

Reputation: 17171

The reason you're getting null is because you're using readObject on ObjectInputString, but you haven't serialized any Java objects. ObjectInputString.readObject is to be used with ObjectOutputString.writeObject.

The PrintWriter docs state explicitly that

It does not contain methods for writing raw bytes, for which a program should use unencoded byte streams.

You should only use PrintWriter for text. It exposes helpful methods that you may be familiar with because System.out has the print interface.

You should only really use ObjectOutput/InputStream when writing and reading serialized Java Objects. The serialization format is binary data (unlike JSON/XML for example). These objects must implement the Serializable interface.

You can improve performance of writing and reading unencoded byte streams by use BufferedOutputStream and BufferedInputStream respectively.

In general, classes with suffix "Reader" and suffix "Writer" are for text encoded streams. They contain helpful methods for parsing strings and lines from text streams. They should never be used for transferring binary data.

In your example you're only writing text data to a file and reading that text data back, so use:

oPW = new PrintWriter(new FileOutputStream("data.txt"));
oPW.println("1");

for writing and

oOIS = new BufferedReader(new FileInputStream("data.txt"));
String s = oOIS.readLine(); // "1"

for reading.

If you were reading and writing binary data, you would do this instead:

os = new FileOutputStream("data.bin");
os.write(new byte[]{ 1, 2, 3 });

and read:

is = new FileInputStream("data.bin");
byte[] buf = new byte[3];
is.read(buf); // buf now equals {1, 2, 3}

If you were reading and writing Java objects, you would do this instead:

oos = new ObjectOutputStream(new FileOutputStream("data.bin"));
Foo foo = new Foo(...);
oos.writeObject(foo);

and read:

ois = new ObjectInputStream(new FileInputStream("data.bin"));
Foo foo = (Foo) ois.readObject();

Upvotes: 4

Related Questions