Issue Details (XML | Word | Printable)

Key: XADISK-98
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Minor Minor
Assignee: Nitin Verma
Reporter: romaerzhuk
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
xadisk

Safe close FileInput/OutputStreams

Created: 07/Jan/12 09:09 AM   Updated: 27/Aug/13 07:22 AM   Resolved: 19/Aug/13 06:14 PM
Component/s: None
Affects Version/s: 1.2
Fix Version/s: 1.2.2

Time Tracking:
Not Specified

File Attachments: 1. Text File Safe-close-streams.patch (13 kB) 07/Jan/12 05:16 PM - romaerzhuk


Tags:
Participants: Nitin Verma and romaerzhuk


 Description  « Hide

FileIOUtility uses unsafe close operation. Any exceptions lead to leaks file descriptors, for example:

public static void copyFile(File src, File dest, boolean append) throws IOException {
        FileChannel srcChannel = new FileInputStream(src).getChannel();
        FileChannel destChannel = new FileOutputStream(dest, append).getChannel();

        // Any exceptions lead to leaks file descriptors!
        long contentLength = srcChannel.size();
        long num = 0;
        while (num < contentLength) {
            num += srcChannel.transferTo(num, NativeXAFileSystem.maxTransferToChannel(contentLength - num), destChannel);
        }

        destChannel.force(false);
        srcChannel.close();
        destChannel.close();
    }

Correct code:

public static void copyFile(File src, File dest, boolean append) throws IOException {
        FileInputStream srcIn = null;
        FileOutputStream destOut = null;
        try {
          srcIn = new FileInputStream(src);
          destOut = new FileOutputStream(dest, append);
          FileChannel srcChannel = srcIn.getChannel();
          FileChannel destChannel = destOut.getChannel();
          long contentLength = srcChannel.size();
          long num = 0;
          while (num < contentLength) {
              num += srcChannel.transferTo(num, NativeXAFileSystem.maxTransferToChannel(contentLength - num), destChannel);
          }

          destChannel.force(false);
        } finally {
          close(srcIn);
          close(destOut);
        }
    }
    static void close(Closeable c) {
      if (c != null) {
        try {
          c.close();
        } catch (Throwable t) {
           logger.warn("Unable to close: " + t);
        }
      }
    }