What is the difference between using a BufferedReader around the StringReader in the following code vs using the StringReader only? By loading up the DOM in line 2 of both examples, it seems like the BufferedReader is not necessary?
InputSource is = new InputSource(new StringReader(html));
Document dom = XMLResource.load(is).getDocument();
VS
InputSource is = new InputSource(new BufferedReader(new StringReader(html)));
Document dom = XMLResource.load(is).getDocument();
In this particular case, I see no benefit. In general there are two benefits:
The oh-so-handy readLine() method is only defined in BufferedReader rather than Reader (irrelevant here)
BufferedReader reduces IO where individual calls to the underlying reader are potentially expensive (i.e. fewer chunky calls are faster than lots of little ones) - again, irrelevant for StringReader
Cut and paste fail?
EDIT: My original answer below. The below isn't relevant in this case, since the buffered reader is wrapping a StringReader, which wraps a String. So there's no buffering to be performed, and the BufferedReader appears to be redundant. You could make an argument for using best/consistent practises, but it would be pretty tenuous.
Possibly the result of a copy/paste, or perhaps an IDE-driven refactor too far!
BufferedReader will attempt to read in a more optimal fashion.
That is, it will read larger chunks of data in one go (in a configurable amount), and then make available as required. This will reduce the number of reads from disk (etc.) at the expense of some memory usage.
To quote from the Javadoc:
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
The BufferedReader version was copied from some code that used to read from a FileReader?
Related
I often keep making menu-driven programs for which the User requires to enter his choice many times.
That's why , I wanna know-
What edge does a 'Scanner' object provides over a 'BufferedReader' object or vice-versa?
and **How to take mutliple inputs using a 'BufferedReader' object ?(without using loops)"
P.S.- I know can that characters(Parsed) in BufferedReader
Read this article
here
BufferedReader
A BufferedReader is a simple class meant to efficiently read from the underling stream
read() or readLine() could cause bytes to be read from the file, converted into characters, and then returned, which can be very inefficient
Efficiency is improved appreciably if a Reader is warped in a BufferedReader.
BufferedReader is synchronized, so read operations on a BufferedReader can safely be done from multiple threads
Scanner
Scanner can do all that a BufferedReader can do and at the same level of efficiency
Scanner can parse the underlying stream for primitive types and strings using regular expressions
I suggest to use BufferedReader because it throws the exception immediately
If I call IOUtils.toString(reader); it returns correct string value. Second call returns "". Reset does not supported by reader
How can I solve this situation?
You can't make the Reader "re-readable" if it doesn't support mark() and reset(). But you could use the String returned from the call you've shown to create a StringReader any number of times, and read those as needed (or use mark() and reset() on a single instance to re-read it as needed.)
Use a java.io.Reader that does support reset, such as CharArrayReader (see http://download.oracle.com/javase/6/docs/api/java/io/CharArrayReader.html).
A BufferedReader also supports reset() of a limited number of characters if a mark is set.
More generally the markSupported method indicates whether the implementation of Reader you are using supports mark/reset (thanks to comment from Bala R pointing that out).
I am really confused about the purpose of various io classes, for example, If we have BufferedWriter, why we need a PrintWriter?
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = null;
while(s=br.readline()!=null) {
PrintWriter fs = new PrintWriter(new FileWriter(file));
fs.println(s);
}
if the BufferedWriter can not help? I just do not understand the difference between these io classes, can someone explain me?
They have nothing to do with each other. In all truth, I rarely use PrintWriter except to convert System.out temporarily. But anyway.
BufferedWriter, like BufferedReader/BufferedInputStream/BufferedOutputStream merely decorates the enclosed Writer with a memory buffer (you can specify the size) or accept a default. This is very useful when writing to slow Writers like network or file based. (Stuff is committed in memory and only occasionally to disk for example) By buffering in memory the speed is greatly increased - try writing code that writes to say a 10 mb file with just FileWriter and then compare to the same with BufferedWriter wrapped around it.
So that's BufferedWriter. It throws in a few convenience methods, but mostly it just provides this memory buffer.
PrintWriter mostly is a simple decorator that adds some specific write methods for various types like String, float, etc, so you don't have to convert everything to raw bytes.
Edited:
This already has come up
The PrintWriter is essentially a convenience class. If you want to quickly and easily blast out a line of text to e.g. a log file, PrintWriter makes it very easy.
Three features:
The print and println methods will take any data type and do the conversion for you. Not just String.
The relatively new format method is worth its weight in gold. Now it's as simple in Java as in C to output a line of text with C-style format control.
The methods never throw an exception! Some programmers are horrified at the possibility of never hearing about things going wrong. But if it's a throwaway program or doing something really simple, the convenience can be nice. Especially if output is to System.out or System.err which have few ways of going wrong.
The main reason to use the PrintWriter is to get access to the printXXX methods (like println(int)). 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 writing to the file.
I have always been slightly confused with the amount of different IO implementations in Java, and now that I am completely stuck in my project development, I was taking my time to read up on useful stuff meanwhile.
I have realized that there is no newbie-friendly comparison (apart from short explanation at API for Writer class) between the different subclasses of the Writer class. So I figured I'd fire away the question, what are those different subclasses good for?
For example, I usually use a FileWriter wrapped with a BufferedWriter for my outputs to files but I have always been irritated by the fact that there is no println() like method, and one has to use newLine() every second line (to make the output human readable). PrintWriterhas the println() method but no constructor that supports appending however...
I'd really appreciate if you could give me your two cents from your experience, or a nice guide/how-to you might have stumbled upon.
EDIT: Thanks for the replies everyone, I really appreciate the info passed on here. It's a bit unfortunate that the whole append() thing ended up being in focus, it merely meant it as an example. My question was mostly referring to the need and use of all the different implementations, which I guess was mentioned somewhat in a couple of the answers.
It's hard to pick one answer as accepted, since there are three really solid answers, each has contributed to my understanding of the problem. I am gonna have to go with Anon, this time as he's got the least amount of rep. points (I presume he's new on SO). He's 15 answers some of which are really well formulated, and 0 questions asked. Good contribution I'd say, and that is worth promoting.
That being said, ColinD and Jay also provided really good answers, and have pointed out interesting ideas. Especially Jay's comment about Java automatically wrapping a BufferedWriter was worth noting. Thanks again guys, really appreciated!
The java.io classes generally follow the Decorator pattern. So, while PrintWriter does not have the specific constructor you might want, it does have a constructor that takes another Writer, so you can do something like the following:
FileOutputStream fos = null;
try
{
fos = new FileOutputStream("foo.txt");
PrintWriter out = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(fos, "UTF-8")));
// do what you want to do
out.flush();
out.close();
}
finally
{
// quietly close the FileOutputStream (see Jakarta Commons IOUtils)
}
As a general usage note, you always want to wrap a low-level Writer (eg FileWriter or OutputStreamWriter) in a BufferedWriter, to minimize actual IO operations. However, this means that you need to explicitly flush and close the outermost Writer, to ensure that all content is written.
And then you need to close the low-level Writer in a finally block, to ensure that you don't leak resources.
Edit:
Looking at MForster's answer made me take another look at the API for FileWriter. And I realized that it doesn't take an explicit character set, which is a Very Bad Thing. So I've edited my code snippet to use a FileOutputStream wrapped by an OutputStreamWriter that takes an explicit character set.
FileWriter is generally not an acceptable class to use. It does not allow you to specify the Charset to use for writing, which means you are stuck with whatever the default charset of the platform you're running on happens to be. Needless to say, this makes it impossible to consistently use the same charset for reading and writing text files and can lead to corrupted data.
Rather than using FileWriter, you should be wrapping a FileOutputStream in an OutputStreamWriter. OutputStreamWriter does allow you to specify a charset:
File file = ...
OutputStream fileOut = new FileOutputStream(file);
Writer writer = new BufferedWriter(new OutputStreamWriter(fileOut, "UTF-8"));
To use PrintWriter with the above, just wrap the BufferedWriter in a PrintWriter:
PrintWriter printWriter = new PrintWriter(writer);
You could also just use the PrintWriter constructor that takes a File and the name of a charset:
PrintWriter printWriter = new PrintWriter(file, "UTF-8");
This works just fine for your particular situation, and actually does the exact same thing as the code above, but it's good to know how to build it by wrapping the various parts.
The other Writer types are mostly for specialized uses:
StringWriter is just a Writer that can be used to create a String. CharArrayWriter is the same for char[].
PipedWriter for piping to a PipedReader.
Edit:
I noticed that you commented on another answer about the verbosity of creating a writer this way. Note that there are libraries such as Guava that help reduce the verbosity of common operations. Take, for example, writing a String to a file in a specific charset. With Guava you can just write:
Files.write(text, file, Charsets.UTF_8);
You can also create a BufferedWriter like this:
BufferedWriter writer = Files.newWriter(file, Charsets.UTF_8);
PrintWriter doesn't have a constructor that takes an "append" parameter, but FileWriter does. And it seems logical to me that that's where it belongs. PrintWriter doesn't know if you're writing to a file, a socket, the console, a string, etc. What would it mean to "append" on writes to a socket?
So the right way to do what you want is simply:
PrintWriter out=new PrintWriter(new BufferedWriter(new FileWriter(myfile, append)));
Interesting side note: If you wrap an OutputStream in a PrintWriter, Java automatically inserts a BufferedWriter in the middle. But if you wrap a Writer in a PrintWriter, it does not. So nothing is gained by saying:
PrintWriter out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(myfile))));
Just leave off the BufferedWriter and the OutputStreamWriter, you get them for free anyway. I have no idea if there is some good reason for the inconsistency.
It's true that you can't specify a character encoding in a FileWriter as ColinD notes. I don't know that that makes it "unacceptable". I almost always am perfectly happy to accept the default encoding. Maybe if you're using a language other than English this is an issue.
The need to wrap Writers or OutputStreams in layers was confusing to me when I first started using Java. But once you get the hang of it, it's no big deal. You just have to bend your mind into the write framework. Each writer has a function. Think of it like, I want to print to a file, so I need to wrap a FileWriter in a PrintWriter. Or, I want to convert an output stream to a writer, so I need an OutputStreamWriter. Etc.
Or maybe you just get used to the ones you use all the time. Figure it out once and remember how you did it.
You can create an appending PrintWriter like this:
OutputStream os = new FileOutputStream("/tmp/out", true);
PrintWriter writer = new PrintWriter(os);
Edit: Anon's post is right about both using a BufferedWriter in between and specifying the encoding.
I'm a Java newbie and stuck with this:
BufferedReader br1 = new BufferedReader(new InputStreamReader(System.in));
and
InputStreamReader ISR = new InputStreamReader(System.in);
BufferedReader BR = new BufferedReader(ISR);
What is the difference between them?
Also, is it compulsory to throw IOException when i'm getting inputs from user?
thanks.
The only difference is that the second form explicitly saves the reference to the InputStreamReader to a variable, which may or may not be useful depending on if you do something with it afterwards.
No difference, just a matter of preference.
Those methods throw checked exceptions, so you're obliged to either handle them if you can or throw to the calling method.
The difference is that the second one is more verbose and uses a temporary variable for the InputStreamReader. You get the first version by substituting ISR with new InputStreamReader(System.in).
But both do the same thing. Advantage of the the later one is that you can still access the InputStreamReader later in your code through the variable ISR (if you have/want to).
- Answer to 1st question
There is absolutely no difference except that you will create a reference to InputStreamReader also which again you can avoid....I personally prefer avoiding it
- Answer to 2nd question
I/O Exceptions are checked exceptions i.e exceptions are checked at compile time while we have unchecked exceptions also in Java which are checked at run time
For more on checked and unchecked exceptions you can refer here
There's no real difference between the two other than the fact that the first does not allow you to distinguish between exceptions from the instantiation of the two objects without careful inspection of the exception.
Actually second variant allows you to use ISR directly, in this case it can cause some problems.
But second variant also allows you to close ISR if closing BR fails.
No, it is not compulsory. It is better to show him human readable message.
They will result in the same thing. a BufferedReader based on System.in in BR and br1.
If you need the ISR later on for some other reason then you would go with that version first. Just a matter of preference really, shorthand vs verbose.
No difference, just first form is more compact and efficient if you might say because no extra reference for InputStreamReader is created.
Well,
The question has been answered comprehensively. Yet, I would like to stress to use the first syntax since you can avoid the extra reference allocated. Moreover, allocating the extra reference has the potential of making the garbage collector in delaying its job. It does not necessarily mean that it would not garbage collect, but still it poses a slight overhead.
So, the answer would be try to use the first syntax at all times except that you need to do some manipulations with ISR variable later.