Reputation: 649
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.
Upvotes: 31
Views: 62790
Reputation: 15729
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:
Some other links:
inputstream and reader in Java IO
InputStream vs InputStreamReader
Upvotes: 52
Reputation: 6552
If you want to change the encoding, use OutputStreamWriter instead of a FileOutputStream. FileOutputStream is a convinient class for writing character files. It uses default encoding.
Force encoding to UTF-8 as the following:
OutputStreamWriter osw = new OutputStreamWriter(
new FileOutputStream(exportPath),
Charset.forName("UTF-8").newEncoder()
);
Upvotes: 2
Reputation: 687
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.
Upvotes: 14
Reputation: 365
This is from here
In java.io you either do byte IO or character IO. Byte IO can be used for any form of data without any interpretation of what that data represents. Character IO is meant for, well, information that is represented as sequences of characters.
For byte IO we have various types of InputStream/OutputStream classes like the FileOutputStream from your example 1). For character data whe have various forms of Reader/Writer classes like the FileWriter from your example. Buffering can be done in both cases, hence the BufferedWriter and BufferedOutputStream classes.
To do character IO characters will at some point have to be converted to byte data using some form of encoding. FileWriter does that for you, which is why it has a constructor that takes the encoding along with the file name. Common encodings include UTF-8, UTF-16 and US-ASCII.
OutputStreamWriter is a class that only does the encoding of characters. That is why it is a Writer and its constructor takes an OutputStream as parameter with an optional encoding parameter.
If you omit the explicit encoding specifications both FileWriter and ByteArrayOutputStream will use the default encoding for your platform. This is something to be very careful with since it will vary among different JVMs.
Upvotes: 3