Reputation: 600
I have the root directory, and the files,which is nested in the root directory(they can be in child directories). I wanna create a list of relative paths those files. I wrote the code, but replacement doesn't work.
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()));
}
}
}
For example: i have the root directory "E:\test", and i have the file "E:\test\test2\1.txt". I want to replace the root directory for the path file, and return "test2\1.txt". But i always recieve "E:\test\test2\1.txt". What the problem with my replacement?
Upvotes: 1
Views: 1030
Reputation: 4162
You need to relativize your paths. On a sidenote: java 8 introduced The Files.find
method which will greatly simplify your collectFileList
method.
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());
}
}
}
Upvotes: 2
Reputation: 14618
Relativize!
There is 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".
Example
Path dir = Path.of("/var/lib");
Path file = Path.of("/var/lib/someapp/1.txt");
Path relative = dir.relativize(file);
System.out.print(relative);
Output
someapp/1.txt
Upvotes: 5