Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DataOutputStream#writeBytes(String) vs BufferedWriter#write(String)

I would like to create a HTML file for my report. The content in the report can be created either by using BufferedWriter#write(String)

File f = new File("source.htm");
BufferedWriter bw = new BufferedWriter(new FileWriter(f));
bw.write("Content");

or by using DataOutputStream#writeBytes(String)

File f = new File("source.htm");
DataOutputStream dosReport = new DataOutputStream(new FileOutputStream(f)); 
dosReport.wrtiteBytes("Content");

Is one of them better than the other? Why is it so?

like image 497
Java Beginner Avatar asked Dec 03 '13 13:12

Java Beginner


People also ask

What is a DataOutputStream?

A data output stream lets an application write primitive Java data types to an output stream in a portable way. An application can then use a data input stream to read the data back in. Since: JDK1.0 See Also: DataInputStream.

When should I use DataOutputStream?

You use the DataOutputStream to write the data to e.g. a file, and then use the DataInputStream to read the data again.

What type of class is DataOutputStream?

Java DataOutputStream class allows an application to write primitive Java data types to the output stream in a machine-independent way. Java application generally uses the data output stream to write data that can later be read by a data input stream.


3 Answers

If you're writing out text then you should use a Writer, which handles the conversion from unicode characters (Java's internal representation of strings) into an appropriate character encoding such as UTF-8. DataOutputStream.writeBytes simply outputs the low-order eight bits of each char in the string and ignores the high-order eight bits entirely - this is equivalent to UTF-8 for ASCII characters with codes below 128 (U+007F and below) but almost certainly wrong for anything beyond ASCII.

Rather than a FileWriter, you should use an OutputStreamWriter so you can select a specific encoding (FileWriter always uses the platform's default encoding, which varies from platform to platform):

File f = new File("source.htm");
BufferedWriter bw = new BufferedWriter(
  new OutputStreamWriter(new FileOutputStream(f), "UTF-8"));
bw.write("Content");
like image 180
Ian Roberts Avatar answered Sep 23 '22 22:09

Ian Roberts


Firstly, the DataOutputStream in your 2nd example serves no useful purpose1. Indeed, if your Strings contain characters that don't fit into 8 bits, the writeBytes(String) method is going to mangle the text. Get rid of it. The Data streams are designed for reading and writing fine-grained binary data. For plain bytes, use a plain (or buffered) Input or Output stream.

Secondly, in this specific use-case where you writing the entire output is a single write operation, the BufferedWriter doesn't add any value either.

So in this case. you should be comparing:

    File f = new File("source.htm");
    Writer w = new FileWriter(f);
    w.write("Content");

versus

    File f = new File("source.htm");
    OutputStream os = new FileOutputStream(f); 
    os.write("Content".getBytes());

To my mind, the first version looks simpler and cleaner. And it is best to use the Reader and Writer stacks for text I/O ... because that's what they were designed for. (They take care of the encoding and decoding issues, cleanly and transparently.)

You could benchmark them if you really need to know which is faster (on your system!) but I suspect there is not a lot of difference ... and that the first version is faster.

1 - I think DataOutputStream has buffering under the covers, but for this use-case, buffering does not help performance.


In use-cases where you are performing multiple (small) writes instead of on big one, there is a significant performance advantage in using a BufferedWriter (or a BufferedOutputStream) instead of an unbuffered writer or stream.


The other point is that both versions of your code is using the platform's default character encoding to encode the output file. It may be more appropriate to use a specific encoding independently of the default, or make this a configuration or command line parameter.

like image 28
Stephen C Avatar answered Sep 26 '22 22:09

Stephen C


OutputStream:

This abstract class is the superclass of all classes representing an output stream of bytes. An output stream accepts output bytes and sends them to some sink.

Applications that need to define a subclass of OutputStream must always provide at least a method that writes one byte of output.

For example:

OutputStream os = new FileOutputStream("test.txt");

BufferedWriter

Writes text to a character-output stream, buffering characters so as to provide for the efficient writing of single characters, arrays, and strings. The buffer size may be specified, or the default size may be accepted. The default is large enough for most purposes.

A newLine() method is provided, which uses the platform's own notion of line separator as defined by the system property line.separator. Not all platforms use the newline character ('\n') to terminate lines. Calling this method to terminate each output line is therefore preferred to writing a newline character directly.

In general, a Writer sends its output immediately to the underlying character or byte stream. Unless prompt output is required, it is advisable to wrap a BufferedWriter around any Writer whose write() operations may be costly, such as FileWriters and OutputStreamWriters.

For example:

 PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));
like image 42
Sanjay Nagare Avatar answered Sep 24 '22 22:09

Sanjay Nagare