What is the better way to close IOs? [closed] - java

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
See the codes :
I usually do like below
RandomAccessFile raf = null;
try {
// do something ...
} catch (IOException e) {
// logger
} finally {
try {
if (null != raf) {
raf.close();
}
} catch (IOException e) {
// logger
}
}
Then I see I can do this in Java8
try (RandomAccessFile raf = ... ) {
// do something ...
} catch (IOException e) {
// logger
}
It seems a good way.
Looks like Java do the job to close IO.
edit 1
Personally, I like the 2nd way.
But is it good to use and has a high performance?

With Java 7 or higher, if the resource implements AutoCloseable, best practice is to use try-with-resources:
try (
RandomAccessFile raf = /*construct it */
) {
// Use it...
}
The resource will be closed automatically. (And yes, the catch and finally clauses are optional with try-with-resources.)
Regarding the code in your question:
Re the main catch block: "log and forget" is generally not best practice. Either don't catch the exception (so the caller can deal with it) or deal with it correctly.
In the catch block in your finally where you're closing, you're quite right not to allow that to throw (you could mask the main exception), but look at the way the spec defines try-with-resources and consider following that pattern, which includes any exception from close as a suppressed exception.

Related

Close this "FileOutputStream" sonar again [duplicate]

This question already has an answer here:
Sonar: How to use try-with-resources to close FileOutputStream
(1 answer)
Closed 5 years ago.
I am having the trouble of close the "FileOutputStream" from sonar . Eventhough I closed the file. From the document of Sonar I donĀ“t understand the error.
I looked at the post
SONAR issue - Close this FileInputStream.
This also not solving my problem.
public void trainL2lSupport(String training_path, String model_path) throws Exception {
BasicConfigurator.configure();
String[] options = { "-s 1" };
FileOutputStream ms = new FileOutputStream(model_path); // This one is producing the error.
classifier.setOptions(options);
logger.info(msg + classifier.globalInfo());
loader.setFile(new File(training_path));
Instances data_set = loader.getDataSet();
data_set.setClassIndex(data_set.numAttributes() - 1);
classifier.buildClassifier(data_set);
Evaluation evaluation = new Evaluation(data_set);
evaluation.crossValidateModel(classifier, data_set, 40, new Random(1));
logger.info(evaluation.toSummaryString());
logger.info(msg1 + timer.stop());
// oos = new ObjectOutputStream(ms);
try {
ObjectOutputStream oos = new ObjectOutputStream(ms);
oos.writeObject(classifier);
oos.flush();
oos.close();
logger.info(msg3+ evaluation.toSummaryString());
logger.info(msg1 + timer.stop());
logger.info("File closed safetly");
} catch(Exception e) {
}
finally {
ms.close();
}
}
How to solve it ?
Use the try-with-resources statement.
If an exception is thrown from any of the lines of code before the try block, the FileOutputStream is never closed. Hence the Sonar warning.
Also, indent your code, don't catch Exception (you should have another warning for that), and don't ignore exceptions like you're doing.

Multithreading file reading [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I have a bunch of files I want to read, but each files are encrypted and compressed. I would like to speed up the process by using each core to open a file, decrypt it, and decompress it. Then pass to the next file that isn't being used.
Right now I have a for loop that reads one file at a time decrypt it, decompress and pass to the next file.
How to do it?
I would assume that file IO is probably more of a bottleneck than the processing. Either way, reading files in parallel will like cause little more than hard drive thrashing - possibly an SSD or high end RAID would cope.
I would structure the program thusly:
main Thread reads files and dumps them to a BlockingQueue
other threads form a ThreadPool and take() from the queue
Lets assume you have some method void doMagicStuff(byte[] file) that does whatever with the files.
public static void main(String[] args) throws Exception {
final BlockingQueue<byte[]> processingQueue = new LinkedBlockingQueue<>();
final ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
final AtomicBoolean done = new AtomicBoolean(false);
IntStream.range(0, Runtime.getRuntime().availableProcessors()).forEach(i -> {
executorService.submit(() -> {
while (!done.get() || !processingQueue.isEmpty()) {
try {
doMagicStuff(processingQueue.take());
} catch (InterruptedException e) {
//exit
return;
}
}
});
});
final Path folder = Paths.get("blah/blah");
try (final Stream<Path> files = Files.list(folder)) {
files.filter(Files::isRegularFile)
.map(file -> {
try {
return Files.readAllBytes(file);
} catch (IOException e) {
throw new RuntimeException(e);
}
}).forEach(processingQueue::add);
}
done.set(true);
executorService.shutdown();
executorService.awaitTermination(Integer.MAX_VALUE, TimeUnit.DAYS);
}
public static void doMagicStuff(final byte[] data) {
//MAGIC MAGIC
}
I would use paralelStream() e.g.
Map<String, String> allFiles =
Files.walk(Paths.get("dir"))
.parallel()
.filter(f -> f.toString().endsWith(".gz"))
.collect(Collectors.toMap(f -> f.toString(), f -> decryptAndUncompress(f)));

FileInputStream / ObjectInputStream: StreamCorruptedException: Wrong format [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
When reading a serialized object from a file, I get:
java.io.StreamCorruptedException: Wrong format: 0
The object, which implements Serializable is saved and restored as such:
Save:
try {
FileOutputStream fileOutputStream = getContext().openFileOutput("gameState.ser", Context.MODE_PRIVATE);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(gameAssets);
} catch (Exception e) {
e.printStackTrace();
}
Restore:
try {
FileInputStream fileInputStream = getContext().openFileInput("gameState.ser");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
gameAssets = (GameAssets) objectInputStream.readObject();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Since you haven't posted the surrounding code, I am not sure if this is the case, or the source of the error.
But you should always close your streams after writing to them.
Make sure all the fields on gameAssets are serializeable. If one of them is not an exception can be printed into the file you created which can cause an exception on read of that file.

How much code to put in try-catch block [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Is there a "best practice" for how much code to put inside a try/catch block?
I have posted 3 different scenarios below.
I did not include behavior in each catch block and i did not include the finally block. This was to improve readability for viewers. Assume each catch does something differently. And assume the finally will be closing the stream. Just trying to create an easy to read example for future readers.
Control, no try/catch.
Code with 1 try/catch for each place needed.
Code with only 1 try/catch surrounding whole code block.
What is generally accepted as the best practice and why?
Scenario 1
Code without try/catch, just for control.
BufferedReader bufferedReader = new BufferedReader(new FileReader("somepath"));
String line;
while ((line = bufferedReader.readLine()) != null) {
Object object = new Object();
this.doSomething(object);
}
bufferedReader.close();
Scenario 2
Code with a try/catch block for each individual place needed.
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new FileReader("somepath"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
String line;
try {
while ((line = bufferedReader.readLine()) != null) {
Object object = new Object();
this.doSomething(object);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
Scenario 3
Code with 1 try/catch surrounding the whole block of code.
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader("somepath"));
String line;
while ((line = bufferedReader.readLine()) != null) {
Object object = new Object();
this.doSomething(object);
}
bufferedReader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
You should scope your try/catches based on the following criteria:
do you need to do different things based on where the exception came from?
do you need to do different things based on which exception was thrown?
what code needs to be skipped (aka is "invalid") when a given exception is thrown?
answering these questions will enable you to determine the appropriate scope for any try/catch block.
I'd put as little in the try-catch as possible.
This allows you to very easily move pieces of code into separate methods which is a good coding practice (obeying single responsibility principle; see the book "Clean Code: A Handbook of Agile Software Craftsmanship" by Robert C. Martin).
Another advantage is that you can quickly identify which code actually can throw an exception.
Scenario 2 seems a bit extreme though, and since the method is pretty small, Scenario 3 seems like the best choice.
However, you need to have your "close" statement in a finally block.
This is a matter of opinion. I've seen each of these patterns a lot.
Pattern 1 is only good when your method can throw the excpetions and have something up the caller chain handle that. That is often desireable. However, since the close call is not in a finally block, it might not be called. At least, use a try-finally block.
Pattern 2 isn't good, since if the first try-catch block handles an exception, the rest of the method is useless.
Pattern 3 is okay, but not great, as printing stack traces hides the fact that the operation failed. What will the caller do if it thinks the operation occurred when it didn't. Also, the closes might not have happened, which can lead to program failure.
In pseudo code, this variant of pattern 3 is better:
Declare Streams, connections, etc.
try
Initialize streams, connections, etc,
Do work.
catch (optional)
Catch and handle exceptions.
Do not simply log and ignore.
finally
Close connections and streams in reverse order.
Remember, closing these objects can throw,
so catch exceptions the close operation throws.
End.
If you are using Java 7, use try-with-resources:
try (BufferedReader bufferedReader = new BufferedReader(new FileReader("somepath"))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
Object object = new Object();
this.doSomething(object);
}
}
Have IOExceptions bubble up to the caller.
You should go with the third scenario.
If the bufferedReader hits an exception then on creation in the second scenario then it you try to readLine() on it, it will hit another exception. No point in raising multiple exceptions for the same problem.
You should also close your bufferedReader in the finally block.
BufferedReader bufferedReader;
try {
bufferedReader = new BufferedReader(new FileReader("somepath"));
String line;
while ((line = bufferedReader.readLine()) != null) {
Object object = new Object();
this.doSomething(object);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bufferedReader != null)
bufferedReader.close();
}
I consider an Exception being an uncoditionally returned result type. So when I work with try-catch sections, I'm trying to answer questions
Should I handle an unexpected result here or should I propagate it on a higher level?
Which unexpected results should I handle?
How to handle them?
In 95% of the cases I don't go further than the first point, so I just propagate the errors.
For file processing I use try-with-resources an re-throw the IOException with throw new RuntimeException(e).
I think it's similar with how much code to put in method. Try to write try/catch/finally which takes no more than one screen. I want to say it's not a problem to wrap entire method body into try{} block, but you should separate this code into several methods if it became too long.
You example with one try/catch each doesn't make sense because you just print a stack trace and continue - knowing already that it will be a failure. You might as well try/catch the whole lot, or add throws SomeException to the method signature and let the calling method decide what went wrong.
Also, don't worry about squeezing too much inside a try/catch. You can always extract that code into another method. Readability is one of the single most important aspects of programming.
The third option is certainly best. You don't want your try/catch block to become unwieldy, but in this example, it is short enough that you do not need to divide it as you have done in your second option.
Not scenario 2. If the FileReader or BufferedReader constructor throws, then bufferedReader will be null but the next try/catch will still execute. Therefore you'll get an (uncaught) exception at bufferedReader.readLine -- a NullPointerException. Between scenarios 1 and 3, I generally like 3 more because it doesn't require the caller to catch. BTW, you don't need to catch FileNotFoundException explicitly, because it inherits from IOException and therefore that catch block will catch both.
jtahlborn already has the correct answer.
Unfortunately sometimes, proper exception handling can be pretty bloated.
One should be ready to deal with it, if required.
Another possible scenario are nested try-catch blocks.
Consider:
BufferedReader bufferedReader = new BufferedReader(new FileReader("somepath"));
try {
String line;
while ((line = bufferedReader.readLine()) != null) {
Object object = new Object();
try {
this.doSomething(object);
} catch (InvalidArgumentException iae) {
throw new RuntimeErrorException("Failed to process line " + line + ", iae);
} catch (ParserWarning e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
bufferedReader.close();
}

catch Fildnot found exception e and a try method [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Well I have this problem and I dont know whats wrong with the codeing,
catch (FilenotFoundException e){
system.out.println("File not found");
}
try
{
FileReader freader = new FileReader("MyFile.txt");
}
}
Its asking for what the error is?? I thought it may be the e not being capitalized is that the reason?
A try{} block should be followed by a catch{} block or finally{} block, you have reversed it.
Use like this: -
try {
FileReader freader = new FileReader("MyFile.txt");
} catch (FileNotFoundException e){
System.out.println("File not found");
}
As per Java Naming Convention: -
Class Names start with a capital letter, and all subsequent word also start with capital letter. So, FilenotFoundException should be FileNotFoundException
And, system should be -> System.
A catch{} block follows a try{} block, not the other way around.
Also, FilenotFoundException should be FileNotFoundException. I doubt it will compile with the alternate spelling. Likewise with system vs. System, as indicated in #Rohit Jain's answer.
It should be otherway. try followed by catch.
try
{
FileReader freader = new FileReader("MyFile.txt");
}catch (FileNotFoundException e){
System.out.println("File not found");
}
Since Java 7:
try( FileReader freader = new FileReader("MyFile.txt"))
{
use freader
}// try
catch( IOException e)
{
e.printStackTrace();
}
catch block should follow try
try {
//code that exception might occur
}
catch(Exception ex) {
//catch the exception here.
}
your try block should either be followed by catch or finally.
try {
//code that exception might occur
}
finally {
//close your resources here
}

Categories