9 Replies Latest reply: Feb 15, 2010 12:37 AM by 763890 RSS

    Issue with close() method of BufferedReader class and FileInputStream class

    763890
      I have written the following code to a text file, called hello,txt from Windows. Everything works fine but I am trying to figure out whether calling of close() method of aforemetioned class is appropriate or necessary thing to do.

      Here are the questions:
      1. Is it necessary to call close method in this senario? And why? [it seems to me that everything gets cleaned up automatically anyways at the end of each call to the method when called from main()]

      2. If the answer for No.1 is yes, then in which order each close method should be called? Or, does the order of calling close method matter anyways?

      3. Is the reason for why in No.1 is that because calling close method on each object is a necessary step to do when dealing with mutli-thread?

      Thanks for your help in advance!
           /**
            * Below is an example to clarify my questions
            */
           void readWinFile() {
                File objFile = new File("hello.txt");
                FileInputStream fileStream = null;
                BufferedReader bfReader = null;
      
                try {
                     fileStream = new FileInputStream(objFile);
                     bfReader = new BufferedReader(
                                        new InputStreamReader(fileStream, "MS932"));
      
                     int tmp;
                     while ((tmp = bfReader.read()) != -1) {
                          System.out.print((char)tmpLine);
                     }
                } catch (FileNotFoundException e) {
                     System.err.printf("File: %s Not Found @ DIR = %s", 
                                         objFile.getName(), objFile.getParent());
                } catch (UnsupportedEncodingException e) {
                     System.err.printf("Internal failure: %s", e);
                } catch (IOException e) {
                     System.err.printf("File: %s close failure", objFile.getName());
      *          } finally {*
      *               if (bfReader != null) {*
      *                    try {*
      *                         bfReader.close();*
      *                    } catch (IOException e) {*
      *                         e.printStackTrace();*
      *                    }*
      *               }*
      *               if (fileStream != null) {*
      *                    try {*
      *                         fileStream.close();*
      *                    } catch (IOException e) {*
      *                         e.printStackTrace();*
      *                    }*
      *               }*
      *          }*     
      }
      Edited by: Jay-K on Feb 14, 2010 8:50 PM

      Edited by: Jay-K on Feb 14, 2010 8:52 PM
        • 1. Re: Issue with close() method of BufferedReader class and FileInputStream class
          763890
          Sorry, the lines with asterisks is the section in question

          Edited by: Jay-K on Feb 14, 2010 8:58 PM
          • 2. Re: Issue with close() method of BufferedReader class and FileInputStream class
            699554
            Jay-K wrote:
            1. Is it necessary to call close method in this senario?
            Yes! Always!
            And why? [it seems to me that everything gets cleaned up automatically anyways at the end of each call to the method when called from main()]
            To avoid resource leaks.
            To automatically flush the stream.
            To close any subsequence streams.
            2. If the answer for No.1 is yes, then in which order each close method should be called? Or, does the order of calling close method matter anyways?
            Closing the outer stream will close any subsequent inner stream.
            3. Is the reason for why in No.1 is that because calling close method on each object is a necessary step to do when dealing with mutli-thread?
            It's vital that any resource that requires manual closing such as a BufferedReader or BufferedWriter is closed as soon as it is not used. A classic example was many years ago when I was first started learning about I/O. I used a BufferedWriter to write to a file but for some strange reason after I had finished writing, half of the file was missing. Then after reading the API I soon realized that the stream needed to be closed, which implicitly calls flush().
            Thanks for your help in advance!
            Your welcome

            Mel
            • 3. Re: Issue with close() method of BufferedReader class and FileInputStream class
              763890
              Melanie_Green wrote:
              ...
              To avoid resource leaks.
              Does it mean that although in most of cases any type of Reader or Stream gets cleaned up properly by design in Java, but there are chances for JRE to screw up by eating up memory resource without properly releasing it, which cause memory leaks.

              I wonder in what circumstances the leaks would occur by not calling close method.
              To automatically flush the stream.
              To close any subsequence streams.
              Straightforward answer. Thanks.
              Closing the outer stream will close any subsequent inner stream.
              So, for the sample code here, I only need to call a close method on BufferedReader object (bfReader) to get stream properly closed, am I right?

              It's vital that any resource that requires manual closing such as a BufferedReader or BufferedWriter is closed as soon as it is not used. A classic example was many years ago when I was first started learning about I/O. I used a BufferedWriter to write to a file but for some strange reason after I had finished writing, half of the file was missing. Then after reading the API I soon realized that the stream needed to be closed, which implicitly calls flush().
              Thanks for the realistic and impressive example of yours. It definitely assured me that I should always be careful not to forget closing streams.
              For that, we could just call the write method as needed and call the close method to flush and close the stream in the finally block,right?

              Thanks,

              Jay
              • 4. Re: Issue with close() method of BufferedReader class and FileInputStream class
                800322
                Jay-K wrote:
                Does it mean that although in most of cases any type of Reader or Stream gets cleaned up properly by design in Java, but there are chances for JRE to screw up by eating up memory resource without properly releasing it, which cause memory leaks.

                I wonder in what circumstances the leaks would occur by not calling close method.
                Pretty much every native resource, most notably DB connections because those even remain open after the client process terminates. But ports or file handlers are similar; note that a JVM does not necessarily terminate just because you close your program in "extreme cases" (shared use of JVM). In an app server this is certainly never the way. And even if it does, as long as your app is running, the stuff is certainly never released.

                Another misconception seems to be that objects are automatically GCed the moment they run out of scope. This is not true.

                And lastly, objects should not rely on their finalizers to release native resources, and should rather provide close/release methods. This is a common paradigm, and that's also why releasing the file handle won't work by simply letting the reader instance run out of scope. Nobody notifies the underlying OS.
                So, for the sample code here, I only need to call a close method on BufferedReader object (bfReader) to get stream properly closed, am I right?
                Yes, you are.
                For that, we could just call the write method as needed and call the close method to flush and close the stream in the finally block,right?
                yup.
                • 5. Re: Issue with close() method of BufferedReader class and FileInputStream class
                  763890
                  Hello CeciNEstPasUnProgrammeur,

                  Thank you for taking your time and doing all these write-up for me.
                  CeciNEstPasUnProgrammeur wrote:
                  Pretty much every native resource, most notably DB connections because those even remain open after the client process terminates. But ports or file handlers are similar; note that a JVM does not necessarily terminate just because you close your program in "extreme cases" (shared use of JVM). In an app server this is certainly never the way. And even if it does, as long as your app is running, the stuff is certainly never released.
                  What you meant is that if my app runs on an app server, which shared the use of JVM with multiple apps, without properly closing ports or file handlers could cause JVM to keep retaining the native resource allocated for my app. In case of that, the resource leaks would occur.

                  On the other hand, if my app runs on an app server, which do not share the use of JVM, the leaks would be less likely to happen even if the ports or file handlers are not manually closed. (It could be a very poor design but technically I could reply on their finalizers to clean up the mess)

                  >
                  Another misconception seems to be that objects are automatically GCed the moment they run out of scope. This is not true.
                  Is there any documentation somewhere that you could refer me to? I would like to figure out why objects are not auto-GCed when they run out of their scope.

                  >
                  And lastly, objects should not rely on their finalizers to release native resources, and should rather provide close/release methods. This is a common paradigm, and that's also why releasing the file handle won't work by simply letting the reader instance run out of scope. Nobody notifies the underlying OS.
                  I see, so the JVM here interacts with the underlying OS to acquire sufficient native resource for its apps to run. Without explicit closing, which would make JVM not to notify underlying OS to release acquired resource. Am I on the ball here?

                  Thanks,
                  Jay
                  • 6. Re: Issue with close() method of BufferedReader class and FileInputStream class
                    EJP
                    What you meant is that if my app runs on an app server, which shared the use of JVM with multiple apps, without properly closing ports or file handlers could cause JVM to keep retaining the native resource allocated for my app. In case of that, the resource leaks would occur.
                    Actually that's not what he meant at all. If your app runs in an app server the JVM will essentially never exit, so your leaks can occur.
                    On the other hand, if my app runs on an app server, which do not share the use of JVM, the leaks would be less likely to happen
                    Why?
                    Is there any documentation somewhere that you could refer me to? I would like to figure out why objects are not auto-GCed when they run out of their scope.
                    Because there is no documentation that says that they are.
                    I see, so the JVM here interacts with the underlying OS to acquire sufficient native resource for its apps to run.
                    Obviously but he is talking about specific resources like file handles, which are both acquired from and release to the OS.
                    • 7. Re: Issue with close() method of BufferedReader class and FileInputStream class
                      763890
                      ejp wrote:
                      Actually that's not what he meant at all. If your app runs in an app server the JVM will essentially never exit, so your leaks can occur.
                      What if it's a command-line module reside on single client machine.
                      On the other hand, if my app runs on an app server, which do not share the use of JVM, the leaks would be less likely to happen
                      Why?
                      Hypothetically, I was trying to firgure out if there are possibilities that the leaks would be less likely to happen.
                      Is there any documentation somewhere that you could refer me to? I would like to figure out why objects are not auto-GCed when they run out of their scope.
                      Because there is no documentation that says that they are.
                      Well, that makes the point. It would be better if there are some sort of documentation somewhere that make it crystal clear for beginners.
                      • 8. Re: Issue with close() method of BufferedReader class and FileInputStream class
                        EJP
                        What if it's a command-line module reside on single client machine.
                        Then the JVM will exit, obviously. That doesn't relieve you of the obligation to close streams however.
                        Hypothetically, I was trying to firgure out if there are possibilities that the leaks would be less likely to happen.
                        So you were asking, not telling? In which case the answer is no, no difference. Leaks will happen unless you code against them in all the ways you've been told here.
                        Because there is no documentation that says that they are.
                        Well, that makes the point. It would be better if there are some sort of documentation somewhere that make it crystal clear for beginners.
                        It would be better if you didn't rely on features that don't exist and aren't documented. Are Sun really obliged to document everything that Java doesn't do? It would be a long list.