使用Java nio中的files walk()函数读取文件

8

我正在使用流API读取文件,我调用readFile()方法来迭代循环,在第一个循环中,我得到了路径值,如何删除该路径值,因为这导致数组索引超出范围异常。文件命名转换是“FileName_17072018”。

public class RemoveCVVFilesjob {

    public static void main(String[] args) throws IOException {
        List<String> fileList;
        fileList = readFile();

        for (String str : fileList) {
            String[] strArr = str.split("_");
            System.out.println(strArr[1]);
        }
    }

    private static List<String> readFile() throws IOException {

        try (Stream<Path> paths = Files.walk(Paths.get("D:\\Projects\\Wallet\\CVVFiles"))) {

            List<String> list = paths.map(path -> Files.isDirectory(path) ? 
                path.getFileName().toString() + '/' : 
                path.getFileName().toString()).collect(Collectors.toList()
            );
            return list;
        }
    }

如果您需要文件路径,请使用过滤器检查它是否为文件,如果是文件,则收集它。并且不确定所有文件是否遵循xxx_xxxx模式。 - mallikarjun
在第一次迭代调用readfile方法后,我得到了文件路径,在第二次迭代中我得到了文件名,那么我该如何避免在第一次迭代中获取文件路径? - Tejal
2个回答

6
你的split()是正确的,但是你在流中使用的map()似乎不正确,因为你同时收集了目录和文件。
所以你没有收集到预期的值:即具有XXX_XXX模式的String
请注意,map()不是用于过滤而是用于转换。
请改用filter()来仅过滤文件:
List<String> list = paths.filter(Files::isRegularFile)
                         .map(p -> p.getFileName()
                                    .toString())
                         .collect(Collectors.toList());

2
问题在于不仅文件,而且目录本身也会进入流中。例如:
D:\Projects\Wallet\CVVFiles
D:\Projects\Wallet\CVVFiles\FileName_17072018.txt
D:\Projects\Wallet\CVVFiles\FileName_18072018.txt

没有过滤器时,映射结果为:
[CVVFiles, FileName_17072018.txt, FileName_18072018.txt]

然后它在获取由分隔符_ 分割结果数组的第二个元素时失败,其位于第一个项目(即目录)。为使其正常工作,请过滤掉目录:

List<String> list = paths
    .filter(Files::isRegularFile)
    .map(path -> path.getFileName().toString())
    .collect(Collectors.toList());

你可能会发现有趣的是 paths.peek(System.out::println).map...,以了解进入map管道的内容。


我建议你使用Files::isRegularFile,它与!isSymbolicLink() && !isDirectory() && !isOther();完全相同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接