繁体   English   中英

我应该关闭FileChannel吗?

[英]Should I close the FileChannel?

我今天遇到了一个我们的实用工具类的问题。 它是文件的助手,包含一些静态文件复制例程。 以下是与测试方法一起提取的相关方法。

问题是有时setLastModified调用失败,返回false。

在我的PC上(Windows 7,最新的Java),我有时会收到“setLastModified failed”消息(大约25次中的1000次)。

我现在通过删除FileChannel.close调用解决了这个问题,但我更愿意理解为什么会发生这种情况,即使这是正确的解决方案。

有没有其他人得到同样的问题?

private void testCopy() throws FileNotFoundException, IOException {
  File src = new File("C:\\Public\\Test-Src.txt");
  File dst = new File("C:\\Public\\Test-Dst.txt");

  for (int i = 0; i < 1000; i++) {
    copyFile(src, dst);
  }
}

public static void copyFile(final File from, final File to) throws FileNotFoundException, IOException {
  final String tmpName = to.getAbsolutePath() + ".tmp";
  // Copy to a .tmp file.
  final File tmp = new File(tmpName);
  // Do the transfer.
  transfer(from, tmp);
  // Preserve time.
  if (!tmp.setLastModified(from.lastModified())) {
    System.err.println("setLastModified failed!");
  }
  // In case there's one there already.
  to.delete();
  // Rename it in.
  tmp.renameTo(to);
}

public static void transfer(final File from, final File to) throws IOException {
  FileInputStream in = null;
  FileOutputStream out = null;
  try {
    in = new FileInputStream(from);
    out = new FileOutputStream(to);
    transfer(in, out);
  } finally {
    if (null != in) {
      in.close();
    }
    if (null != out) {
      out.close();
    }
  }
}

public static void transfer(final FileInputStream from, final FileOutputStream to) throws IOException {
  FileChannel srcChannel = null;
  FileChannel dstChannel = null;
  //try {
    srcChannel = from.getChannel();
    dstChannel = to.getChannel();
    srcChannel.transferTo(0, srcChannel.size(), dstChannel);
  //} finally {
  //  if (null != dstChannel) {
  //    dstChannel.close();
  //  }
  //  if (null != srcChannel) {
  //    srcChannel.close();
  //  }
  }
}

编辑:我已经将代码更改为仅关闭Streams而不是FileChannel因为研究表明关闭FileChannel也会关闭Stream

在对包含java库源的各个站点进行一些研究之后,它看起来非常像FileChannel.close最终调用其父对象的FileInputStream.closeFileOutputStream.close

这告诉我你应该关闭FileChannel或Stream,而不是两者

鉴于此,我正在改变我的原始帖子以反映一种正确的方法,即关闭Stream而不是Channel s。

如果您使用的是Java 7,则可以使用Files.copy(Path source,Path target,CopyOption ... options)进行此操作,以避免编写,测试和调试您自己的实现。

或者,考虑使用外部库,例如Apache Commons IO 具体来说,你会发现FileUtils.copyFile(File srcFile,File destFile)有趣:

/** 
 * Copies a file to a new location preserving the file date.
 * [...]
 * @param srcFile  an existing file to copy, must not be <code>null</code>
 * @param destFile  the new file, must not be <code>null</code>
 * [...]
 */
public static void copyFile(File srcFile, File destFile) throws IOException

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM