9

I am using try-with-resource block in my code, wondering is there a need to close the resource at the end of the method or not needed?

try (S3Object object = s3.getObject(new GetObjectRequest(bucketName, key));
  BufferedReader br = new BufferedReader(new InputStreamReader(object.getObjectContent()));
  BufferedWriter bw = new BufferedWriter(new FileWriter(new File("output.txt")))){
  String line;

  while((line=br.readLine())!=null){
    bw.write(line);
    bw.newLine();
    bw.flush();
  }
}
ZhaoGang
  • 4,491
  • 1
  • 27
  • 39
Maana
  • 640
  • 3
  • 9
  • 22
  • 5
    No, there isn't if you do it right... – deHaar Dec 12 '18 at 14:35
  • 1
    @deHaar, so the logic is wrote above is right ? No need of finally block at the end – Maana Dec 12 '18 at 14:38
  • 1
    You also don’t need `bw.flush()`. Closing the BufferedWriter (whether automatically or manually) will flush it. – VGR Dec 12 '18 at 14:45
  • 1
    No, there is no need for a `finally` block that closes the resources. See the answer below given by @ZhaoGang. I think you have to open a bracket behind the `try`-with resource. – deHaar Dec 12 '18 at 14:46
  • 1
    Which resource? The `object` (really bad name, as it doesnt tell us much about the object) ... or the reader/writer you use inside the body? – GhostCat Dec 12 '18 at 14:51
  • @GhostCat they are not used in the body.. – ZhaoGang Dec 12 '18 at 14:53
  • @ZhaoGang So opening and writing to a Writer in the body isn't using a resource?! – GhostCat Dec 12 '18 at 14:54
  • @GhostCat They are among the multiple resources – ZhaoGang Dec 12 '18 at 14:57
  • The encoding for reading and writing is the current platform encoding, so non-portable. And ` Files.newBufferedWriter` or even `Files.copy` save on typing. – Joop Eggen Dec 12 '18 at 15:00
  • Can some one please suggest me how can I improve above method ? thanks! – Maana Dec 12 '18 at 15:10
  • By saying they are not used in the body.. in my previous comment what I really want to say is they are not defined in the body but the try-with-resource clause, together with the s3object. Sorry for bad English – ZhaoGang Dec 12 '18 at 15:44
  • I appreciate the quick accept ;-) – GhostCat Dec 13 '18 at 14:14

3 Answers3

10

No.

The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.

And if you are using a java 6 or older:

Prior to Java SE 7, you can use a finally block to ensure that a resource is closed regardless of whether the try statement completes normally or abruptly.

Update:

You may declare one or more resources in a try-with-resources statement.

as you have used in your code.

ZhaoGang
  • 4,491
  • 1
  • 27
  • 39
4

No, You don't. Let's take a look at an example of a try-catch-finally and try-with-resource

Scanner scanner = null;
try {
    scanner = new Scanner(new File("test.txt"));
    while (scanner.hasNext()) {
        System.out.println(scanner.nextLine());
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
} finally {
    if (scanner != null) {
        scanner.close();
    }
}

This is your regular try-catch-finally in this you are closing the scanner in the finally block. Now lets take a look at try-with-resource

try (Scanner scanner = new Scanner(new File("test.txt"))) {
    while (scanner.hasNext()) {
        System.out.println(scanner.nextLine());
    }
} catch (FileNotFoundException fnfe) {
    fnfe.printStackTrace();
}

You don't need to close the scanner here since it closes it self after the try block has done executing. For more ref visit this blog

SamHoque
  • 2,978
  • 2
  • 13
  • 43
2

You don't have to close resources that you defined in the try clause. But, given your example, you also have this in the body of the try:

BufferedWriter bw = new BufferedWriter(new FileWriter(new File("output.txt"))))

and your code is notclosing that resource. And that is wrong (and keeping file system handles open is most likely a real resource leak).

In other words: you probably want to add bw to your try-with-resources clause, so it sits along with the definition of S3Object object ( see here for an example ).

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • 1
    BufferedWriter is in try only clause only. – Maana Dec 12 '18 at 14:56
  • can you please give me some reference/code how to I can close more then one resource if I use try-with-resource, thanks – Maana Dec 12 '18 at 15:07
  • `try (S3Object object = s3.getObject(new GetObjectRequest(bucketName, key)); BufferedReader br = new BufferedReader(new InputStreamReader(object.getObjectContent())); BufferedWriter bw = new BufferedWriter(new FileWriter(new File("/tmp/output.txt")))) {` sorry but I am still confused s3, br and bw are in try clause only. – Maana Dec 12 '18 at 15:24
  • 1
    It goes like try ( clause ) { body } catch ... so, yes, you move the definition of all resources you want to be closed automatically from the "body" to the "clause" part – GhostCat Dec 12 '18 at 16:00
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/185165/discussion-between-jay-and-ghostcat). – Maana Dec 12 '18 at 20:00