Java - what is usual practice for simple reading from text files?
I'm messing about with Java, after a long hiatus, and I'm running into my usual problems with its complexity.
I have what should be a simple problem, but what with InputStreams, InputReaders, and dealing with finally and close(), I'm not seeing an obvious answer.
I'm in the main() function of a simple command-line app. I've parsed my command-line, and I have a input filename. This contains either the path to a text file or "-", which means that the program should read from System.in.
What I want is a String containing the contents of the file (or the remaining contents of System.in). And what I am ending up with is way too complex, so I'm looking for the simple way to do it.
Question 1: Given an InputStream (which might be System.in or it might be a FileInputStream() I opened myself, what's the simplest way to read all of its contents into a String? The various readAll() methods I've been seeing returned byte arrays, for which there is a place, but it's not what I am looking for.
Question 2: What is the usual idiom for making sure that any reader I open will always be closed?
If I were writing in C++, I'd have put the close() in my class's destructor, and I'd be sure that close() would be called when my object fell out of scope.
If I were writing in C#, I'd have used a "using" block, and I'd have the same guarantee.
I'm sure this can be done in Java, but my attempts so far have seemed cumbersome.
If I try:
try
{
InputStream inStream = new InputStream(...);
}
finally
{
inStream.close();
}
I get complains that "inStream cannot be resolved".
But if I try
InputStream inStream = null;
try
{
inStream = new InputStream(...);
}
finally
{
if (inStream != null)
inStream.close();
}
I get "Unhandled exception type IOException.
So now I'm at:
InputStream inStream = null;
try
{
inStre开发者_开发技巧am = new InputStream(...);
}
finally
{
try
{
if (inStream != null)
inStream.close();
}
catch (IOException ex)
{
}
}
And that just seems ludicrous.
What is the usual pattern?
You might want to try using Apache Commons IO to wrap some of this stuff for you. An example:
import org.apache.commons.io.FileUtils;
File f = new File("mystuff.txt");
String contents = FileUtils.readFileToString(f);
Or, if you're starting with a stream:
import org.apache.commons.io.IOUtils;
InputStream is = new InputStream(...);
String contents = IOUtils.toString(is);
And much, much more :-).
I'd use
InputStream in = ...;
String content = IOUtils.toString(in);
IOUtils.closeQuietly(in);
That's IOUtils.toString() and IOUtils.closeQuietly() from Commons IO.
I would normally do something like the following: (NOTE: I haven't shown how inStream gets it contents.)
InputStream inStream = null;
BufferedReader in = null;
try {
StringBuilder builder = new StringBuilder();
in = new BufferedReader(new InputStreamReader(inStream));
String str;
while ((str = in.readLine()) != null) {
builder.append(str).append("\n");
}
}
catch(Exception e) {
}
finally {
if(in != null) {
try {
in.close();
} catch (IOException e) {}
}
if(inStream != null) {
try {
inStream.close();
} catch (IOException e) {}
}
}
As for your complaint about exception handling, it makes sense. If something fails you may or may not want to know. Its giving you the option of how you want to deal with it.
Upgrade to Java 7, then you'll be able to benefit from automatic resource management (the try-with-resources statement):
try (InputStream inStream = new InputStream(...)) {
// ...
}
This is borrowed from C#'s using
statement.
If you have the ability to use Groovy, it's a lot easier:
def file = new File('/my/path/test.txt')
def contents = file.getText()
Groovy will allow you to drop into any Java methods you need for those cases where complexity is required and it compiles to Java files so works well with existing classes.
精彩评论