我应该关闭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,而不是两者

鉴于此,我正在改变我的原始post以反映一种正确的方法,即关闭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 null * @param destFile the new file, must not be null * [...] */ public static void copyFile(File srcFile, File destFile) throws IOException