有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

如何在Java中创建相对路径?

我有根目录和文件,它们嵌套在根目录中(它们可以在子目录中)。我想创建这些文件的相对路径列表。代码是我写的,但替换不起作用

public class FileManager {
private Path rootPath;
private List<Path> fileList = new ArrayList<Path>();

public FileManager(Path rootPath) throws IOException{
    this.rootPath = rootPath;
    collectFileList(rootPath);
}

private void collectFileList(Path path) throws IOException{
    if (Files.isRegularFile(path)){
        if (!fileList.contains(path.getParent())){
                String result_path =  path.toAbsolutePath().toString().replaceAll(rootPath.toString(),"");
                fileList.add(Paths.get(result_path));
        }
    }else if (Files.isDirectory(path)){
        for (File file:path.toFile().listFiles()
             ) {
            collectFileList(Paths.get(file.getAbsolutePath()));
        }

}
}

例如: 我有根目录“E:\test”,还有文件“E:\test\test2\1.txt”。我想替换路径文件的根目录,并返回“test2\1.txt”。但我总是收到“E:\test\test2\1.txt”。我的替代品有什么问题


共 (2) 个答案

  1. # 1 楼答案

    相对化

    Path relativize(Path other)

    Relativization is the inverse of resolution. This method attempts to construct a relative path that when resolved against this path, yields a path that locates the same file as the given path. For example, on UNIX, if this path is "/a/b" and the given path is "/a/b/c/d" then the resulting relative path would be "c/d". Where this path and the given path do not have a root component, then a relative path can be constructed. A relative path cannot be constructed if only one of the paths have a root component. Where both paths have a root component then it is implementation dependent if a relative path can be constructed. If this path and the given path are equal then an empty path is returned.

    For any two normalized paths p and q, where q does not have a root component,

    p.relativize(p .resolve(q)).equals(q) When symbolic links are supported, then whether the resulting path, when resolved against this path, yields a path that can be used to locate the same file as other is implementation dependent. For example, if this path is "/a/b" and the given path is "/a/x" then the resulting relative path may be "../x". If "b" is a symbolic link then is implementation dependent if "a/b/../x" would locate the same file as "/a/x".

    示例

    Path dir = Path.of("/var/lib");
    Path file = Path.of("/var/lib/someapp/1.txt");
    Path relative = dir.relativize(file);
    System.out.print(relative);
    

    输出

    someapp/1.txt
    
  2. # 2 楼答案

    你需要相对化你的路径。另一方面:Java8引入了Files.find方法,这将大大简化collectFileList方法

    import static java.util.stream.Collectors.toList;
    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.util.List;
    import java.util.stream.Stream;
    
    public class FileManager {
        private final Path rootPath;
        private final List<Path> fileList;
    
        public FileManager(Path rootPath) throws IOException{
            this.rootPath = rootPath;
            this.fileList = collectFileList(rootPath);
        }
    
        private static List<Path> collectFileList(Path path) throws IOException {
            try (Stream<Path> pathStream = Files.find(
                    path,
                    Integer.MAX_VALUE,
                    (file, attrs) -> attrs.isRegularFile()
            )) {
                return pathStream
                        .map(path::relativize)
                        .collect(toList());
            }
        }
    }