Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OutputStreamWriter vs FileWriter

Tags:

java

I don't understand the difference between these two classes. When would you use one over the one? I know that FileWriter can output characters to a file but so can OutputStreamWriter as far as i know. Here is some code that i tested and they seem to work the same, i'm not adding the exception handling stuff but lets just assume its there.

FileWriter writer = new FileWriter("C:\\Users\\owner\\Desktop\\demo.txt"); writer.write("hello"); writer.close(); 

I also tried this code:

File file = new File("C:\\Users\\owner\\Desktop\\demo.txt"); os = new OutputStreamWriter(new FileOutputStream(file)); os.write("hello"); os.close(); 

Both of these seem to work the same for me. The only time something strange happens is when i try to put an int value in the write() method. For the FileWriter example, my demo.txt is completely empty. For the OutputStreamWriter example i get some weird symbols in my text file. I am reading a java book and the only explanation i get for OutputStreamWriter is that it "converts a stream of characters to a stream of bytes" so shouldn't i be seeing some bytes in my text file in the second example?

Some clarification would be greatly appreciated.

like image 230
i'mhungry Avatar asked Jul 07 '12 00:07

i'mhungry


People also ask

What is the difference between FileOutputStream and FileWriter?

FileWriter writes streams of characters while FileOutputStream is meant for writing streams of raw bytes. FileWriter deals with the character of 16 bits while on the other hand, FileOutputStream deals with 8-bit bytes.

Which is better FileWriter vs BufferedWriter?

FileWriter writes directly into Files and should be used only when the number of writes is less. BufferedWriter: BufferedWriter is almost similar to FileWriter but it uses internal buffer to write data into File. So if the number of write operations is more, the actual IO operations are less and performance is better.

What is the main advantage of using BufferedWriter over FileWriter alone?

If you have a lot of code that appends a single character at a time, however, a BufferedWriter will be much more efficient. As per andrew's comment below, the FileWriter actually uses its own fixed-size 1024 byte buffer. This was confirmed by looking at the source code.

Do I need to close FileWriter?

It is not necessary to close it, because BufferedWriter takes care of closing the writer it wraps.


2 Answers

XXXInputStream and XXXOutputStream (where XXX varies, there's a lot of options) deal with 8-bit bytes. For example, OutputStream.write(byte[] c);

XXXWriter or XXXReader deal with 16-bit chars. For example, Reader.read(char[] cbuf).

OutputStreamWriter converts an OutputStream to a Writer. As you may have guessed, InputStreamReader converts from an InputStream to a Reader. I am unaware of any classes that do the reverse, i.e. convert a Reader to an InputStream.

FileWriter is a Writer that talks to files. Since a Java String internally uses chars (16 bit so they can handle Unicode), FileWriter is the natural class for use with Unicode Strings.

FileOutputStream is an OutputStream for writing bytes to a file. OutputStreams do not accept chars (or Strings). By wrapping it in an OutputStreamWriter you now have a Writer, which does accept Strings.

Now, the real question, is when do you use a Reader/Writer and when a Stream? I've used Java for years and sometimes I get confused too. I believe the following to be correct:

Handy Guide - How to Decide Which to use:

  1. If you are dealing with binary data (e.g. an image) use Streams.
  2. If you are using non-ASCII Unicode characters, e.g. Chinese, use Readers/Writers.
  3. If you are using ordinary ASCII text (the traditional 0-127 characters) you can (usually) use either.

Some other links:

inputstream and reader in Java IO

InputStream vs InputStreamReader

like image 177
user949300 Avatar answered Sep 18 '22 04:09

user949300


There is actually no difference per se, FileWriter is just a convenience class. It extends OutputStreamWriter and creates the needed FileOutputStream itself.

Regarding write(int): that method writes a single character with the specified codepoint to the stream, it does not write a textual representation of the numeric value.

As for the empty file, note that you should always flush the buffer when you want the things you've written flushed to the underlying store (be it a file or a network stream or whatever you can think of). Simply call os.flush() after writing, that should do it.
EDIT: As Thilo has correctly mentioned, closing the stream should already flush it (and all underlying streams).

And last but not least, you should nearly always explicitly specify the charset/encoding you want your Writer to write in. Writers write characters, while OutputStreams write bytes, so you have to specify how those characters should be encoded into bytes. If you don't specify an encoding, the system default gets used, which may not be what you want.

like image 44
2 revs Avatar answered Sep 18 '22 04:09

2 revs