Regarding java's try/catch syntax; are these blocks equivalent? [duplicate] - java

This question already has answers here:
Why should I not wrap every block in "try"-"catch"?
(16 answers)
Closed 5 years ago.
In the following block:
try (final InputStream fis = new BufferedInputStream(Files.newInputStream(f.toPath()));
final ArchiveInputStream ais = factory.createArchiveInputStream(fn, fis)) {
System.out.println("Created " + ais.toString());
ArchiveEntry ae;
while ((ae = ais.getNextEntry()) != null) {
System.out.println(ae.getName());
}
}
is this equivalent to the following block:
try {
final InputStream fis = new BufferedInputStream(Files.newInputS...;
} catch {
System.out.println("Created " + ais.toString());...
}
I stumbled across this syntax for try/catch in an apache common's library, and I'm not really sure how to take it. If I'm not correct in the only assumption that I can think of here, can anybody help me understand it or point me to a reference that explains this syntax? I've googled and searched aplenty on here and haven't been able to find anything applicable, though admittedly my search-fu is not the best.
Thanks in advance!

No. The first is try with resources, which isn't an intuitive name. It's used when you need to use a resource and then close it. It saves you from having to manually close those every time and effectively limits the scope of the resources to within the curly braces.
The latter one is not the same: the resource fis will still be open after the try/catch block has exited. try-with-resources was introduced to fix this issue.

Related

The Properties.load would close the InputStream?

I saw this example, and I didn't see the close() method invoked on the InputStream, so would prop.load() close the stream automatically? Or is there a bug in the example?
The Stream is not closed after Properties.load ()
public static void main(String[] args) throws IOException {
InputStream in = new FileInputStream(new File("abc.properties"));
new Properties().load(in);
System.out.println(in.read());
}
The above code returns "-1" so the stream is not closed. Otherwise it should have thrown java.io.IOException: Stream Closed
Why do you ask when the javadoc of Properties.load(InputStream inStream) says this?
The specified stream remains open after this method returns.
It has been saying that since Java 6.
As EJP said in a comment: Don't rely on arbitrary Internet junk. Use the official Oracle Java documentation as your primary source of information.
The following try-with-resources will close the InputStream automatically (you can add catch and finally if needed):
try (InputStream is = new FileInputStream("properties.txt")) {
// is will be closed automatically
}
Any resource declared within a try block opening will be closed. Hence, the new construct shields you from having to pair try blocks with corresponding finally blocks that are dedicated to proper resource management.
Article by Oracle here: http://www.oracle.com/technetwork/articles/java/trywithresources-401775.html.

Java Deserialization -- file is correctly written to but calling .available() on the ObjectInputStream with the same file path always returns 0 [duplicate]

This question already has answers here:
ObjectInputStream available() method doesn't work as expected (Java)
(5 answers)
Closed 6 years ago.
First of all, I'm new to the site, and found it very helpful for having previous questions of mine that had already been answered, but I couldn't find anything about this specifically, so I hope this hasn't already been answered. This is for a game I'm making where RoadPanel.shopList is a static arraylist that holds all the shops in the map (and they are drawn and updated, etc. from here). shopIn has the same filepath as the file that is (correctly) written to while the game is running (I opened the file to make sure it was being written to properly). I don't know why it says that there are no available files to read from the InputStream, so I'm really stuck...
public static void loadGame() throws ClassNotFoundException, IOException
{
ObjectInputStream shopIn = new ObjectInputStream(new FileInputStream("src/save/shops.ser"));
System.out.println("Available: " + shopIn.available());
while(shopIn.available() > 0)
{
System.out.println("hit");
Shop s = (Shop)shopIn.readObject();
RoadPanel.shopList.add(s);
}
}
Thanks for your help,
pete.
Your code is invalid. available() isn't a test for end of stream. See the Javadoc. And it isn't implemented for some streams, including ObjectInputStream.
You should read until EOFException is thrown.

Why does java.io.File not implement Autocloseable? [duplicate]

This question already has answers here:
Why doesn't java.io.File have a close method?
(6 answers)
Closed 8 years ago.
After upgrading to Java 7 I get the following code flagged by Eclipse:
try (File file = new File(FILE_NAME)) {
file.delete();
}
Error is:
The resource type File does not implement java.lang.AutoCloseable
And Java's documentation doesn't have File listed in the AutoCloseable docs:
http://docs.oracle.com/javase/8/docs/api/java/lang/AutoCloseable.html
So besides adding the catch block, what is the suggested alternative?
As Jeffrey said in the comment to the question, you need to differentiate between a File and an InputStream, e.g. FileInputStream.
There is nothing to close in a File, but there is something to close in a stream or a reader.
try (FileInputStream fs = new FileInputStream (new File(FILE_NAME))) {
// do what you want with the stream
}

If I reinstantiate a Scanner, does the old one close?

I have this code:
Scanner fileReader = new Scanner(myFile);
// some code
fileReader = new Scanner(myFile);
// some more code
fileReader.close();
It does what I want it to (starts the reader again from the top of the file) but have I left a Scanner open by instantiating twice and only closing once? Should I have closed before I reinstantiated? What I have works, but I'd like to know whether it's good practice or not.
If I reinstantiate a Scanner, does the old one close?
Nope.
Should I have closed before I reinstantiated?
Yup.
What I have works, but I'd like to know whether it's good practice or not.
It is bad practice. It is a resource leak. If you do that too much, you are likely to find that new Scanner(myFile) will throw an exception, complaining that it has run out of file descriptors (or something like that).
The recommended practice is to use the try with resources syntax to ensure that the scanner gets closed no matter what. (Or if you are "old school" and / or stuck on Java 6 or earlier ... close the scanner in a finally block ... carefully.)
Example:
try (Scanner fileReader = new Scanner(myFile)) {
// some code
}
try (Scanner fileReader = new Scanner(anotherFile)) {
// some more code
}
It is not necessary to explicitly close either fileReader. Each try has an implicit finally block that calls close on all of the Closeable resources like the Scanner objects we created there.)

How to find out which thread is locking a file in java?

I'm trying to delete a file that another thread within my program has previously worked with.
I'm unable to delete the file but I'm not sure how to figure out which thread may be using the file.
So how do I find out which thread is locking the file in java?
I don't have a straight answer (and I don't think there's one either, this is controlled at OS-level (native), not at JVM-level) and I also don't really see the value of the answer (you still can't close the file programmatically once you found out which thread it is), but I think you don't know yet that the inability to delete is usually caused when the file is still open. This may happen when you do not explicitly call Closeable#close() on the InputStream, OutputStream, Reader or Writer which is constructed around the File in question.
Basic demo:
public static void main(String[] args) throws Exception {
File file = new File("c:/test.txt"); // Precreate this test file first.
FileOutputStream output = new FileOutputStream(file); // This opens the file!
System.out.println(file.delete()); // false
output.close(); // This explicitly closes the file!
System.out.println(file.delete()); // true
}
In other words, ensure that throughout your entire Java IO stuff the code is properly closing the resources after use. The normal idiom is to do this in the try-with-resources statement, so that you can be certain that the resources will be freed up anyway, even in case of an IOException. E.g.
try (OutputStream output = new FileOutputStream(file)) {
// ...
}
Do it for any InputStream, OutputStream, Reader and Writer, etc whatever implements AutoCloseable, which you're opening yourself (using the new keyword).
This is technically not needed on certain implementations, such as ByteArrayOutputStream, but for the sake of clarity, just adhere the close-in-finally idiom everywhere to avoid misconceptions and refactoring-bugs.
In case you're not on Java 7 or newer yet, then use the below try-finally idiom instead.
OutputStream output = null;
try {
output = new FileOutputStream(file);
// ...
} finally {
if (output != null) try { output.close(); } catch (IOException logOrIgnore) {}
}
Hope this helps to nail down the root cause of your particular problem.
About this question, I also try to find out this answer, and ask this question and find answer:
Every time when JVM thread lock a file exclusively, also JVM lock
some Jave object, for example, I find in my case:
sun.nio.fs.NativeBuffer
sun.nio.ch.Util$BufferCache
So you need just find this locked Java object and analyzed them and
you find what thread locked your file.
I not sure that it work if file just open (without locked exclusively), but I'm sure that is work if file be locked exclusively by Thread (using java.nio.channels.FileLock, java.nio.channels.FileChannel and so on)
More info see this question

Categories