我正在尝试获取给定文件夹的所有内容的路径,比如我有一个像这样的文件夹结构:
此文件夹的路径为:c:\\path\\to\\folder\\docs\\
docs
|
+- someFolder (c:\\path\\to\\folder\\docs\\someFolder\\)
| +- someText.txt (c:\\path\\to\\folder\\docs\\someFolder\\someText.txt)
+- movie.mp4 (c:\\path\\to\\folder\\docs\\movie.mp4)
我想做的是:
将路径名称设为
["docs\", "docs\someFolder\someText.txt", "docs\movie.mp4"]
AKA相对路径。我使用Commons IO
列出给定路径中的所有文件和文件夹:
List<String[]> paths = new ArrayList<>();
File f = new File(folderPath);
for (File k : FileUtils.listFilesAndDirs(f, TrueFileFilter.TRUE, TrueFileFilter.TRUE)) {
paths.add(k.getPath().split(Pattern.quote(File.separator)));
}
一种方法是拆分主folderPath
并获取其最后一个索引 - docs
存在的位置(这是我在上面的代码中所做的)。然后迭代paths
数组并将其从0
切片到可以docs
可用的索引。
我尝试过Arrays.asList(k.getPath().split(Pattern.quote(File.separator))).subList(0,6).clear()
,但我不知道如何把它放在ist或数组中。
还有其他选择吗?
更新
我需要替代方案的原因是,我无法将Arrays.asList(k.getPath().split(Pattern.quote(File.separator))).subList(0,6).clear()
添加到数组列表中,因为clear
不会返回任何内容。此外,我还不知道如何将Arrays.asList(k.getPath().split(Pattern.quote(File.separator)))
添加到List<String[]> paths = new ArrayList<>()
列表中,如果我这样做,我会收到错误消息:
Error:(162, 18) java: no suitable method found for add(java.util.List<java.lang.String>)
method java.util.Collection.add(java.lang.String[]) is not applicable
(argument mismatch; no instance(s) of type variable(s) T exist so that java.util.List<T> conforms to java.lang.String[])
method java.util.List.add(java.lang.String[]) is not applicable
(argument mismatch; no instance(s) of type variable(s) T exist so that java.util.List<T> conforms to java.lang.String[])
我不知道这意味着什么,但是如果我将List<String[]> paths = new ArrayList<>()
更改为List<Object> paths = new ArrayList<>()
它会有效,并且Object
会出现问题。这令人困惑。
答案 0 :(得分:1)
我这样做的方式是通过下面的递归方法,我赞成在代码中解释过程:
<script>
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
var zoom_handler = d3.zoom()
.on("zoom", zoom_actions);
zoom_handler(svg);
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().distance(300).id(function(d) {
return d.id;
}))
.force("charge", d3.forceManyBody().strength(-300))
.force("center", d3.forceCenter(width / 2, height / 2));
var g = svg.append("g")
.attr("class", "everything");
var link = g.append("g")
.attr("class", "links")
.selectAll("line")
.data(graph.links)
.enter().append("line")
.style("stroke", linkColour)
.attr("stroke-width", function(d) {
return Math.sqrt(d.value);
});
var node = g.append("g")
.attr("class", "nodes")
.selectAll("g")
.data(graph.nodes)
.enter().append("g")
var circles = node.append("circle")
.attr("r", 20)
.attr("fill", circleColour)
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
var lables = node.append("text") // Labeling for nodes
.text(function(d) {
return d.id;
})
.attr('x', 25)
.attr('y', 6);
node.append("title")
.text(function(d) {
return d.id;
});
simulation
.nodes(graph.nodes)
.on("tick", ticked);
simulation.force("link")
.links(graph.links);
function circleColour(d) {
if (d.group == "1") {
return "SteelBlue";
} else if (d.group == "2") {
return "Lime";
} else {
return "HotPink";
}
}
function linkColour(d){
if(d.type == "A"){
return "DimGrey";
} else {
return "SpringGreen";
}
}
function ticked() {
link
.attr("x1", function(d) {
return d.source.x;
})
.attr("y1", function(d) {
return d.source.y;
})
.attr("x2", function(d) {
return d.target.x;
})
.attr("y2", function(d) {
return d.target.y;
});
node
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
})
};
function zoom_actions() {
g.attr("transform", d3.event.transform)
}
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
}
</script>
修改:
只需通过操作列表中的字符串就可以轻松地查询相对路径,但这将是天真的方法。我能想到的最好的解决方案是再使用一个参数来保存相对路径:
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
// arguments are your folder and the list you
// want to add the results
collectFiles(new File("C:/"), list);
for (String s : list) {
System.out.println(s);
}
}
private static void collectFiles(File folder, ArrayList<String> list) {
// Add the current file/folder to the list
list.add(folder.getAbsolutePath());
// If its not a directory return cause we already add it
if (!folder.isDirectory())
return;
// We found a directory so get all the files in it
File[] listOfFiles = folder.listFiles();
// In case the above returns null return
if (listOfFiles == null)
return;
// For every file in the list
for (File f : listOfFiles) {
// if its a directory do a recursive call
if (f.isDirectory()) {
collectFiles(f, list);
} else {
// we found a file so add it to the list
list.add(f.getAbsolutePath());
}
}
}
你只需称它为:
private static void collectFiles(File folder, String relativePath, ArrayList<String> list) {
// Add the current file/folder to the list
list.add(relativePath);
// If its not a directory return cause we already add it
if (!folder.isDirectory())
return;
// We found a directory so get all the files in it
File[] listOfFiles = folder.listFiles();
// In case the above returns null return
if (listOfFiles == null)
return;
// For every file in the list
for (File f : listOfFiles) {
// if its a directory do a recursive call
if (f.isDirectory()) {
collectFiles(f, relativePath + File.separator + f.getName(), list);
} else {
// we found a file so add it to the list
list.add(relativePath + File.separator + f.getName());
}
}
}
编辑2:你要求方法返回List,所以下面也有那个版本:
File searchFolder = new File("C:\\Users\\Name\\Desktop");
collectFiles(searchFolder, searchFolder.getName(), list);
for (String s : list) {
System.out.println(s);
}
答案 1 :(得分:1)
如果我理解你的要求是正确的,你可以使用字符串替换来为你完成这项工作。
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.TrueFileFilter;
public class DirectoryListing {
public static void main(String[] args) {
String folderPath = "c:\\path\\to\\folder\\docs\\";
String parentDirectory = "docs";
System.out.println(findFilePaths(folderPath, parentDirectory));
}
public static List<String> findFilePaths(String folderPath, String parentDirectory){
List<String> paths = new ArrayList<>();
File f = new File(folderPath);
for (File k : FileUtils.listFiles(f, TrueFileFilter.TRUE, TrueFileFilter.TRUE)) {
paths.add(k.getPath().replace(folderPath, parentDirectory));
}
return paths;
}
}
我的测试目录树:
Fixing common performance problems in React Navigation
使用此运行参数:
String folderPath = "C:\\00docs";
String parentDirectory = "docs";
结果列表如下:
[docs\00\File00.txt, docs\00\File00A.txt, docs\00docs\File00DocsA.txt, docs\01\File01.txt, docs\File00DocsP.txt]
答案 2 :(得分:1)
如果您可以使用NIO,这可以更加简单。
public List<Path> findFilesAsRelativePaths(Path directory) throws IOException {
try (Stream<Path> stream = Files.find(directory, Integer.MAX_VALUE, (path, attrs) -> attrs.isRegularFile())) {
return stream.map(directory::relativize).collect(Collectors.toList());
}
}
这使用java.nio.file.Files.find(Path, int, BiPredicate, FileVisitOption...)
如果您需要String
的路径,则只需拨打Path.toString()
即可。或者,如果您需要File
,则可以使用Path.toFile()
转换它。
此外,如果您还想要目录,可以将(path, attrs) -> attrs.isRegularFile()
更改为(path, attrs) -> true
。虽然使用Files.walk(Path, int, FileVisitOption...)
可能更好。
答案 3 :(得分:1)
要获取相对于其他路径导入的路径,请使用Java Path的relativize
:
//import java.nio.file.Path;
public static void main(String[] args) {
List<String> paths = getPaths("c:\\path\\to\\folder\\docs\\", "c:\\path\\to\\folder");
paths.forEach(p -> System.out.println(p));
}
private static List<String> getPaths(String sourcePath, String sourceParentPath) {
List<String> paths = new ArrayList<>();
getPaths(sourcePath, Paths.get(sourceParentPath), paths);
return paths;
}
private static void getPaths(String sourcePath,Path parent, List<String> paths) {
paths.add(parent.relativize(Paths.get(sourcePath)).toString());
File file = new File(sourcePath);
if( ! file.isDirectory()) {//if directory, search it
return;
}
if(file.list() == null) {//for abstract path or errors
return;
}
for (String fileName: file.list() ){
getPaths((sourcePath+"\\"+fileName), parent, paths);
}
}