代码之家  ›  专栏  ›  技术社区  ›  Timothy Truckle Vincent Boutot

如何使用绝对路径为*目录*创建文件系统对象?

  •  1
  • Timothy Truckle Vincent Boutot  · 技术社区  · 6 年前

    我正在创建一个命令行应用程序,它需要将一些文件(不止一个)输出到 普通文件夹 取决于给定的参数。

    FileSystem .

    我的问题是我不能成功地创建一个 目录 绝对路径 在我的硬盘上:

    public class FileSystemWriteTest {
        public static void main(String[] args) throws IOException {
            Path absolutePath = Paths.get("target", "testpath").toAbsolutePath();
            System.out.println(String.format("user.dir before change:\n %s", System.getProperty("user.dir")));
    
    
            System.setProperty("user.dir", absolutePath.toString());
            System.out.println(String.format("changed user.dir:\n %s", System.getProperty("user.dir")));
            FileSystem defaultSystem = FileSystems.getDefault();
            Path testFilePath = defaultSystem.getPath("test.file");
            System.out.println(String.format("expected to be in changed user.dir:\n %s", testFilePath.toAbsolutePath()));
    
    
            URI uri = absolutePath.toUri();
            System.out.println(String.format("URI: %s", uri));
            FileSystem localFileSystem =
                    FileSystems.newFileSystem(uri, Collections.emptyMap());
            Path file = localFileSystem.getPath("test.txt");
            System.out.println(file.toAbsolutePath());
        }
    }
    

    输出为:

    user.dir before change:
     D:\data\scm-workspace\anderes\Test
    changed user.dir:
     D:\data\scm-workspace\anderes\Test\target\testpath
    expected to be in changed user.dir:
     D:\data\scm-workspace\anderes\Test\test.file
    URI: file:///D:/data/scm-workspace/anderes/Test/target/testpath/
    Exception in thread "main" java.lang.IllegalArgumentException: Path component should be '/'
        at sun.nio.fs.WindowsFileSystemProvider.checkUri(Unknown Source)
        at sun.nio.fs.WindowsFileSystemProvider.newFileSystem(Unknown Source)
        at java.nio.file.FileSystems.newFileSystem(Unknown Source)
        at java.nio.file.FileSystems.newFileSystem(Unknown Source)
        at com.oc.test.filesystem.FileSystemWriteTest.main(FileSystemWriteTest.java:27)
    

    如果我改成 FileSystems.newFileSystem(Path, Classloader) 异常更改为:

    Exception in thread "main" java.nio.file.ProviderNotFoundException: Provider not found
        at java.nio.file.FileSystems.newFileSystem(Unknown Source)
        at com.oc.test.filesystem.FileSystemWriteTest.main(FileSystemWriteTest.java:27)
    

    常规文件 目录 .

    那么我怎样才能创造一个 文件系统 对象 目录 密码 ?

    1 回复  |  直到 6 年前
        1
  •  3
  •   Holger    6 年前

    没有用于创建 FileSystem 具有 chroot 就像语义学。默认文件系统仅支持 file:/// 作为URI,不允许多个实例化。

    在这方面, FileSystems.getDefault().getPath("test.file") 创建一个相对路径,就像 Paths.get("test.file") . 为默认文件系统和其他文件系统创建的相对路径之间的区别在于没有指定其他基本路径时的解析行为(例如调用 toAbsolutePath()

    实现文件系统无关操作的最佳解决方案是让代码接收基 Path 对象,以解析相对路径。

    static void copyTree(Path sourceBase, Path targetBase) throws IOException {
        try {
            Files.walk(sourceBase).forEach(path -> {
                if(Files.isRegularFile(path)) try {
                    Path target = targetBase.resolve(sourceBase.relativize(path).toString());
                    if(!Files.isDirectory(target.getParent()))
                        Files.createDirectories(target.getParent());
                    Files.copy(path, target, StandardCopyOption.COPY_ATTRIBUTES);
                } catch(IOException ex) {
                    throw new UncheckedIOException(ex);
                }
            });
        } catch(UncheckedIOException ex) {
            throw ex.getCause();
        }
    }
    

    对于这种方法,不管您是从一个硬盘驱动器目录复制到另一个硬盘驱动器目录还是一个zip文件系统,还是从一个zip文件系统复制到硬盘驱动器,或者从一个zip文件复制到另一个zip文件,等等。

    sourceBase.relativize(path) ,以获取从源基本路径到实际文件的子路径的相对路径。自相对 实例仍然绑定到代码调用的特定文件系统 toString() targetBase.resolve(…) ,以确保它可以跨不同的文件系统工作。请注意 path.resolve(string) 相当于 path.resolve(path.getFileSystem().getPath(string)) . 如果该方法首先检查两者是否 实例属于同一文件系统,跳过 String