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.
Related
I may be overthinking this, but I just wrote the code:
try (InputStream in = ModelCodeGenerator.class.getClassLoader().getResourceAsStream("/model.java.txt"))
{
modelTemplate = new SimpleTemplate(CharStreams.toString(new InputStreamReader(in, "ascii")));
}
Which means the InputStreamReader is never closed (but in this case we know its close method just closes the underlying InputStream.)
One could write it as:
try (InputStreamReader reader = new InputStreamReader(...))
But this seems worse. If InputStreamReader throws for some reason, the InputStream won't ever be closed, right? This is a common problem in C++ with constructors that call other constructors. Exceptions can cause memory/resource leaks.
Is there a best practice here?
Which means the InputStreamReader is never closed
Eh? In your code it is... And it will certainly handle the .close() of your resource stream as well. See below for more details...
As #SotiriosDelimanolis mentions however you can declare more than one resource in the "resource block" of a try-with-resources statement.
You have another problem here: .getResourceAsStream() can return null; you may therefore have an NPE.
I'd do this if I were you:
final URL url = ModelCodeGenerator.class.getClassLoader()
.getResource("/model.java.txt");
if (url == null)
throw new IOException("resource not found");
try (
final InputStream in = url.openStream();
final Reader reader = new InputStreamReader(in, someCharsetOrDecoder);
) {
// manipulate resources
}
There is a very important point to consider however...
Closeable does extend AutoCloseable, yes; in fact it only differs, "signature wise", by the exception thrown (IOException vs Exception). But there is a fundamental difference in behavior.
From the javadoc of AutoCloseable's .close() (emphasis mine):
Note that unlike the close method of Closeable, this close method is not required to be idempotent. In other words, calling this close method more than once may have some visible side effect, unlike Closeable.close which is required to have no effect if called more than once. However, implementers of this interface are strongly encouraged to make their close methods idempotent.
And indeed, the javadoc of Closeable is clear about this:
Closes this stream and releases any system resources associated with it. If the stream is already closed then invoking this method has no effect.
You have two very important points:
by contract, a Closeable also takes care of all resources associated with it; so, if you close a BufferedReader which wraps a Reader which wraps an InputStream, all three are closed;
should you call .close() more than once, there is no further side effect.
This also means, of course, that you can choose the paranoid option and keep a reference to all Closeable resources and close them all; beware however if you have AutoCloseable resources into the mix which are not Closeable!
But this seems worse. If InputStreamReader throws for some reason, the
InputStream won't ever be closed, right?
That's right (although unlikely, the InputStreamReader constructor doesn't really do much).
The try-with-resources lets you declare as many resources as you'd like. Declare one for the wrapped resource, and another for the InputStreamReader.
try (InputStream in = ModelCodeGenerator.class
.getClassLoader()
.getResourceAsStream("/model.java.txt");
InputStreamReader reader = new InputStreamReader(in)) {...}
Note that getResourceAsStream can potentially return null, which would cause the InputStreamReader constructor to throw a NullPointerException. If you want to deal with that differently, adapt how you retrieve the resource that's meant to be wrapped.
The tutorial linked above presents this example
try (
java.util.zip.ZipFile zf =
new java.util.zip.ZipFile(zipFileName);
java.io.BufferedWriter writer =
java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
) {
with the explanation
In this example, the try-with-resources statement contains two
declarations that are separated by a semicolon: ZipFile and
BufferedWriter. When the block of code that directly follows it
terminates, either normally or because of an exception, the close
methods of the BufferedWriter and ZipFile objects are automatically
called in this order. Note that the close methods of resources are
called in the opposite order of their creation.
What is difference between creating object and then passing it to parameter vs declaring an object as an argument in the constructor of class. Like what is difference between 1) and 2)?
1)
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(isr);
2)
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
Two differences come to mind:
In theory, with the all-in-one construction, if the outer constructor threw an exception, you'd have an instance of the inner object lying around that you never call close on (because you don't have a reference to it that you can use to do that), so it won't get closed until finalization (if then). In practice, I don't think BufferedReader's constructor can throw an exception, but...
This is part of what Java's new try-with-resources statement is designed to help with:
try (
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(isr);
)
{
// do your stuff here
}
Using try-with-resources, you can be sure that even if the second constructor throws, the first object gets closed correctly.
Note that when you use try-with-resources with multiple declarations as above, close is called in the reverse order in which they appear, which is usually exactly what you want (in this case, br.close() is called before isr.close()).
With the all-in-one construction, you're assuming that the outer object will close the object you pass it when you close it (because, again, you have no reference to the inner object to use to close it). This is true of BufferedReader, but may not be universally true. Again try-with-resources helps there, by ensuring that close is called.
If you're dealing with objects that don't need close or similar, there's not much difference between the two at all. It's easier to single-step over the separate statements when debugging than it is the all-in-one construction, but other than that, there's not much in it.
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.
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?