为什么 nio 文件系统不将工作移到 try block 之外?



我正试图使用nio的文件系统来重命名zip文件中的文件。

以下文档中的示例适用于我。

import java.util.*;
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.*;

public class ZipFSPUser {
public static void main(String [] args) throws Throwable {
Map<String, String> env = new HashMap<>(); 
env.put("create", "true");
Path javaPath = Paths.get("C:/test.zip");

try (FileSystem zipfs = FileSystems.newFileSystem(javaPath, env)) {
Path pathInZipfile = zipfs.getPath("/test.txt");        
Files.move( pathInZipfile,pathInZipfile.resolveSibling("/test_changed.txt"), 
StandardCopyOption.REPLACE_EXISTING ); 
} 
}
}

但是当我移除try块时:

FileSystem zipfs = FileSystems.newFileSystem(javaPath, env);
Path pathInZipfile = zipfs.getPath("/test.txt");        
Files.move( pathInZipfile,pathInZipfile.resolveSibling("/test_changed.txt"), 
StandardCopyOption.REPLACE_EXISTING ); 

代码已编译,但文件未重命名。

为什么?

您尝试了什么

你发布的第一个例子是使用try with resources:

try (FileSystem zipfs = FileSystems.newFileSystem(javaPath, env)) {
Path pathInZipfile = zipfs.getPath("/test.txt");
Files.move(pathInZipfile, pathInZipfile.resolveSibling("/test_changed.txt"),
StandardCopyOption.REPLACE_EXISTING);
}

Java教程包括几个例子和更多的解释,但是你遇到的主要问题是:

try-with-resources语句确保每个资源都在语句末尾关闭

在您的第一个示例中;zipfs";正在尝试块结束时自动关闭。


在第二个例子中;尝试";因此,您在不调用close((的情况下创建了一个资源(zipfs(。来自Javadoc:

关闭文件系统将关闭所有打开的频道、目录流、监视服务和其他与该文件系统相关的可关闭对象

跳过对close((的调用将打开这些东西,这就是第二个例子中发生的情况。

FileSystem zipfs = FileSystems.newFileSystem(javaPath, env);
Path pathInZipfile = zipfs.getPath("/test.txt");
Files.move(pathInZipfile, pathInZipfile.resolveSibling("/test_changed.txt"),
StandardCopyOption.REPLACE_EXISTING);

解决方案

为了让你的代码在不使用资源的情况下(安全地(工作,你可以将你的代码更改为以下内容:

  • 声明"zipfs";,赋值为null
  • 创建一个新的";尝试";阻止,做你以前做的任何事情
  • 创建一个新的";最后";关闭zipfs的块(如果它不是null(
FileSystem zipfs = null;
try {
zipfs = FileSystems.newFileSystem(javaPath, env);
Path pathInZipfile = zipfs.getPath("/test.txt");
Files.move(pathInZipfile, pathInZipfile.resolveSibling("/test_changed.txt"),
StandardCopyOption.REPLACE_EXISTING);
} finally {
if (zipfs != null) {
zipfs.close();
}
}

如果你想变得不安全,你可以最后取消尝试,然后在最后加上zipfs.close((。但这是有风险的——如果之前的行出现任何错误,将不会调用close((。

最安全的是使用某种形式的";try";,最简单的方法是使用try with resources。

最新更新