获取所需文件夹及其内容的路径

时间:2018-06-19 02:53:51

标签: java

我正在尝试获取给定文件夹的所有内容的路径,比如我有一个像这样的文件夹结构:

此文件夹的路径为: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会出现问题。这令人困惑。

4 个答案:

答案 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 Pathrelativize

//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);
    }
}