Need for Data Input Stream - java

What is the difference between
FileInputStream fstream = new FileInputStream ("file1.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
and
FileInputStream fstream = new FileInputStream ("file1.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
Do we really need a DataInputStream here?

The use of DataInputStream is a common mistake which I believe comes from copy-and-paste from different pieces of code. You want to read the files as either text e.g. BufferedReader OR binary e.g. DataInputStream. Its highly unlikely you want to use both and trying to is likely to lead to confusion.
For Text which is buffered
BufferedReader br = new BufferedReader(new FileReader(file));
For binary which is buffered
DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));

The significant thing about the object passed to the InputStreamReader() constructor is that it will be the object that will bear the weight of any synchronization holds. If you don't want your FileInputStream to potentially be held up by many calls to it, then the second option is the way to go. See the source of Reader.

FileInputStream is meant for reading streams of raw bytes such as
image data. For reading streams of characters, consider using
FileReader.
A data input stream lets an application read primitive Java data types
from an underlying input stream in a machine-independent way. An
application uses a data output stream to write data that can later be
read by a data input stream.
DataInputStream is not necessarily safe for multithreaded access.
FileInputStream only gives you a very basic interface.
When you're wanting to read numbers, Strings (or even complex Objects) rather than just bytes, that's a pain. So you use a second input stream "wrapping" the first, which gives you a more useful interface. DataInputStream is one of these.

It depends, A data input stream lets an application read primitive Java data types from an underlying input stream in a machine-independent way. An application uses a data output stream to write data that can later be read by a data input stream. Check JavaDoc
BufferedReader : Reads text from a character-input stream, buffering characters so as to provide for the efficient reading of characters, arrays, and lines.
FileInputStream : Using FileInputStream, you will read file data in bytes.

No, there is no need for DataInputStream in your example because you are finally getting a BufferedReader to read data.
What would instead make sense is:
FileInputStream fstream = new FileInputStream ("file1.txt");
BufferedInputStream br = new BufferedInputStream(fstream);
DataInputStream dis = new DataInputStream(br);
Usually this would go hand in hand when you have created "file1.txt" using:
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("file1.txt")));
Edit:
Why is it allowed by Java if it doesn't really make sense? Because this is Decorator pattern and this is one of the disadvantages of Decorator pattern.

Related

I/O Character stream: BufferedReader vs printWriter construction

Why is BufferedReader created as such
BufferedReader br = new BufferedReader(new InputStreamReader(System.in))
while PrintWriter can be simply constructed like these
PrintWriter pw = new PrintWriter(System.out, true);
BufferedReader can't be constructed directly from System.in so it requires InputStreamReader to convert bytes to char, is this to make it human readable? But PrintWriter dosen't require a wrap from char back to bytes why is that so, does Java automate it? Because to a machine everything is 1 & 0 anyway.
so it requires InputStreamReader to convert bytes to char, is this to
make it human readable?
No, it's for performance. Check this to see the difference between them.
And there are BufferedWriter and BufferedReader, they have similar functions and constructors.
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufferedWriter = new BufferedWriter(new PrintWriter(System.out));
First:
- Binary data: byte[], InputStream, OutputStream;
- (Unicode) text: String, char, Reader, Writer;
- Bridges where binary data has some encoding/Charset and is actually text: InputStreamReader, OutputStreamWriter (converting from/to given or default Charset).
Now consider:
System.in is a InputStream.
System.out and System.err are a PrintStream extending from OutputStream.
They are conceived as for binary data, which for Unix is quite normal and useful. For a console however not so useful. However PrintStream might be a design mishap/error: it has text support, also for passing a Charset; it is a half OutputStreamWriter.
So see PrintStream as an old unclean class doing what an OutputStreamWriter + BufferedWriter does, however not being a Writer.
BufferedWriter+OutputStreamWriter has the same complexity (though being reversed) as PrintStream. One also sees Scanner: new Scanner(System.in). This is not a Reader, and has superfluous support for tokenizing. It like PrintStream has the advantage of briefness, but is definitely more unclean for its unneeded overhead. (There are quite a lot of bugs mentioned in StackOverflow on Scanner.)

The role of FileReader and BufferedReader - why wrapp FileReader?

I cannot really grasp what the purpose is for the FileReader and BufferedReader classes in Java.
At docs.oracle one is recommended to wrap a buffered reader around a FileReader object because it's not efficient to use the FileReader directly. Where does the cost or overhead come from?
Let say I have a text file that I want to read into my java program using these classes:
I use FileReader and BufferedReader
FileReader fileReader = new FileReader(new File("text.txt)"); // probably correct???
BufferedReader bufferedReader = new BufferedReader(fileReader);
1) What is the task of the FileReader object here? Is it responsible to make an I/O-request via the OS to the file, and thereafter read bytes? What is the cost with this?
Is it true that the FileReader makes several I/O-requests? Or is the cost when the FileReader object has to converting bytes to characters, character by character?
2) The task of the BufferedReader-object - to refer to the last sentence above. - Is the role for the BufferedReader-object to simply buffer arrays of incoming bytes and THEN convert those to character?
Very grateful for answers
Edit: first of all thanks for incoming answers. But I should have mentioned that its exactly this documentation I have studied. Call me stupid or something - but what is meant by "each read request". WHEN is each read request made? how often?
In general, each read request made of a Reader causes a corresponding read request to be made of the underlying character or byte stream. It is therefore advisable to wrap a BufferedReader around any Reader whose read() operations may be costly, such as FileReaders and InputStreamReaders. For example,
This is mostly why a launched this question - It sounds that the FileReader causes a lot of I/O-request which slows erverthing down.
From oracle docs :
In general, each read request made of a Reader causes a corresponding
read request to be made of the underlying character or byte stream. It
is therefore advisable to wrap a BufferedReader around any Reader
whose read() operations may be costly, such as FileReaders and
InputStreamReaders. For example,
BufferedReader in = new BufferedReader(new FileReader("foo.in"));
will buffer the input from the specified file. Without buffering, each
invocation of read() or readLine() could cause bytes to be read from
the file, converted into characters, and then returned, which can be
very inefficient.
So, as the document clearly suggests, Wrapping a BufferedReader around a FileReader prevents reading of data from the file over and over again. BufferedReader buffers the input.
Java has many I/O classes which may be combined. So you might see something like:
BufferedReader in = new BufferedReader(new InputStreamReader(
new FileInputStream(new File("..."), "UTF-8"));
...
in.close(); // Closes all.
This allows flexible combination. So an XML parser could use Reader, and not care where the text comes from: file, URL, memory. This as opposed to "simpler" languages, where there is no choice of implementation (Map with implementations HashMap, TreeMap).
Now, FileReader and FileWriter are old utility classes to read from and write to a file in the default operating system encoding. So for local files. Not portable (!) to other operating systems, or requiring a fixed encoding.
For this FileReader extends InputStreamReader which reads binary data (an InputStream) using a FileInputStream. It does just that.
However it makes sense to use a larger memory buffer to read, hence the advice; which also is long-standing. Remember performance was an issue in the early times of java.
The only advantage of FileReader-standalone would be for tight memory situations, maybe on a smart phone.

Java: Possible to have more than one type of stream?

Wondering if one can do something like this successfully:
Socket s = new Socket("", 1234);
BufferedInputStream in = new BufferedInputStream(s.getInputStream());
BufferedOutputStream out = new BufferedOutputStream(s.getOutputStream());
ObjectInputStream oin = new ObjectInputStream(s.getInputStream());
ObjectOutputStream out = new ObjectOutputStream(s.getOutputStream());
Or if there's perhaps a better way of doing it. I ask because I want to send raw data over the Buffered I/O streams and use the Object streams as a means of communicating details and establishing a protocol for connection for my program. Right now I'm trying to just use the Buffered streams and use byte arrays for my client/server protocol but I've hit a hiccup where the byte array I receive is not equal to what I expect it to be, so the == operator and .equals() method do not work for me.
You can't use a mix of streams because they are both buffered so you will get corruption and confusion.
Just use the ObjectStreams for everything.
In general, you should only read from or write to one Stream, Reader or Writer for a stream.
Go take a look at How can I read different groups of data on the same InputStream, using different types of InputStreams for each of them? and see if my answer over there helps. It involves tagging the data in an ObjectStream in order to know if it's text or an object.

Performance of DataInputStream\DataOutputStream

I am currently using a buffered streams to read write some files. In between I do some mathematical processing where a symbol is a byte.
To read :
InputStream input = new FileInputStream(outputname)
input.read(byte[] b,int off,int len)
To write :
OutputStream output = new BufferedOutputStream(
new FileOutputStream(outputname),
OUTPUTBUFFERSIZE
)
output.write((byte)byteinsideaint);
Now I need to add some header data, and to support short symbols too. I want to use DataInputStream and DataOutputStream to avoid converting other types to bytes myself and I am wondering if what is their performance.
Do I need to use
OutputStream output = new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream(outputname),
OUTPUTBUFFERSIZE
)
);
to keep the advantages of the data buffering or it is good enough to use
OutputStream output = new DataOutputStream(
new FileOutputStream(outputname)
)
You should add BufferedOutputStream in between. DataOutputStream does not implement any caching (which is good: separation of concerns) and its performance will be very poor without caching the underlying OutputStream. Even the simplest methods like writeInt() can result in four separate disk writes.
As far as I can see only write(byte[], int, int) and writeUTF(String) are writing data in one byte[] chunk. Others write primitive values (like int or double) byte-by-byte.
You absolutely need the BufferedOutputStream in the middle.
I appreciate your concern about the performance, and I have 2 suggestions:
Shrink your streams with java compression. Useful article can be found here.
Use composition instead of inheritance (which is recommended practice anyway). Create a Pipe which contains a PipedInputStream and a PipedOutputStream connected to each other, with getInputStream() and getOutputStream() methods.You can't directly pass the Pipe object to something needing a stream, but you can pass the return value of it's get methods to do it.

Difference between java.io.PrintWriter and java.io.BufferedWriter?

Please look through code below:
// A.class
File file = new File("blah.txt");
FileWriter fileWriter = new FileWriter(file);
PrintWriter printWriter = new PrintWriter(fileWriter);
// B.class
File file = new File("blah.txt");
FileWriter fileWriter = new FileWriter(file);
BufferedWriter bWriter = new BufferedWriter(fileWriter);
What is the difference between these two methods?
When should we use PrintWriter over BufferedWriter?
PrintWriter gives more methods (println), but the most important (and worrying) difference to be aware of is that it swallows exceptions.
You can call checkError later on to see whether any errors have occurred, but typically you'd use PrintWriter for things like writing to the console - or in "quick 'n dirty" apps where you don't want to be bothered by exceptions (and where long-term reliability isn't an issue).
I'm not sure why the "extra formatting abilities" and "don't swallow exceptions" aspects are bundled into the same class - formatting is obviously useful in many places where you don't want exceptions to be swallowed. It would be nice to see BufferedWriter get the same abilities at some point...
The API reference for BufferedWriter and PrintWriter detail the differences.
The main reason to use the PrintWriter is to get access to the printXXX methods like println(). You can essentially use a PrintWriter to write to a file just like you would use System.out to write to the console.
A BufferedWriter is an efficient way to write to a file (or anything else), as it will buffer the characters in Java memory before (probably, depending on the implementation) dropping to C to do the writing to the file.
There is no such concept as a "PrintReader"; the closest you will get is probably java.util.Scanner.
As said in TofuBeer's answer both have their specialties. To take the full advantage of PrintWriter (or any other writer) but also use buffered writing you can wrap the BufferedWriter with the needed one like this:
PrintWriter writer = new PrintWriter(
new BufferedWriter (
new FileWriter("somFile.txt")));
PrintWriter just exposes the print methods on any Writer in character mode.
BufferedWriter is more efficient than , according to its buffered methods.
And it comes with a newLine() method, depending of your system platform, to manipulate text files correctly.
The BufferedReader permits to read a text from file, with bytes converted in characters. It allows to read line by line.
There is no PrintReader, you have to choose another Reader implementation according to the format of your input.
PrintWriter is the most enhanced Writer to write Character data to a file.
The main advantage of PrintWriter over FileWriter and BufferedWriter is:
PrintWriter can communicate directly with the file, and can communicate via some Writer object also.
PrintWriter printwriter = new PrintWriter("blah.txt");
(or)
FileWriter filewriter = new FileWriter("blah.txt");
PrintWriter printwiter = new PrintWriter(filewriter);
We can write any type of Primitive data directly to the file (because we have additional overloaded versions of PrintWriter methods i.e., print() and println()).
printwriter.print(65); //65
bufferedwriter.write(65); //A
printwriter.println(true); //true
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,
Note: Text content in the code blocks is automatically word-wrapped
PrintWriter out =
new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));
will buffer the PrintWriter's output to the file. Without buffering, each invocation of a print() method would cause characters to be converted into bytes that would then be written immediately to the file, which can be very inefficient.
BufferedWriter - Writes text to an output character stream, buffering characters from a character stream.
PrintWriter - Prints formatted representations of objects to a text output stream.
I think that the reason behind using PrintWriter is already mentioned above but one of the important reason is you an pass a file object directly to the PrintWriter constructor which makes it easy to use it.
File file=new File(“newfile.txt”);
PrintWriter pw=new PrintWriter(file);

Categories