Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java8中逐行读取Spring多部分文件的最佳方法_Java_Spring_Java 8 - Fatal编程技术网

在Java8中逐行读取Spring多部分文件的最佳方法

在Java8中逐行读取Spring多部分文件的最佳方法,java,spring,java-8,Java,Spring,Java 8,csv Spring多部分文件的最佳处理方式是什么? 我以前用过类似的方法: public void handleFile(MultipartFile multipartFile){ try{ InputStream inputStream = multipartFile.getInputStream(); IOUtils.readLines(inputStream, StandardCharsets.UTF_8) .str

csv Spring多部分文件的最佳处理方式是什么? 我以前用过类似的方法:

public void handleFile(MultipartFile multipartFile){
    try{
        InputStream inputStream = multipartFile.getInputStream();
        IOUtils.readLines(inputStream, StandardCharsets.UTF_8)
                .stream()
                .forEach(this::handleLine);
    } catch (IOException e) {
        // handle exception
    }
}

private void handleLine(String s) {
    // do stuff per line
}
据我所知,这首先将整个文件加载到内存中的一个列表中,然后再对其进行处理,对于具有数万行的文件,这可能需要相当长的时间

有没有一种方法可以一行一行地处理它,而不用手动实现迭代(即使用
read()
hasNext(
),…)之类的工具)? 我正在为文件系统中的文件寻找类似于此示例的简明内容:

try (Stream<String> stream = Files.lines(Paths.get("file.csv"))) {
        stream.forEach(this::handleLine);
} catch (IOException e) {
    // handle exception
}
try(Stream=Files.line(path.get(“file.csv”)){
forEach(这个::handleLine);
}捕获(IOE异常){
//处理异常
}
公共静态列表readCSV(字符串文件名)引发IOException{
列表记录=新的ArrayList();
try(BufferedReader br=新的BufferedReader(
新文件读取器(文件名))){
弦线;
而((line=br.readLine())!=null){
记录。添加(行);
}
}
退货记录;
}

如果您有InputStream,则可以使用此选项:

InputStream inputStream = multipartFile.getInputStream();
new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))
                    .lines()
                    .forEach(this::handleLine);
在其他情况下:

无论是多部分文件还是有多个独立文件,在Java 8中使用
Stream
API有很多方法可以实现这一点:

解决方案1:

如果您的文件位于不同的目录中,您可以这样做:

try (Stream<Path> stream = Files.walk(Paths.get("/test/ehsan"))) {
    stream.filter(Files::isRegularFile)
            .flatMap(path -> {
                try {
                    return Files.lines(path);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return Stream.empty();
            })
            .forEach(System.out::println);
} catch (IOException e) {
    e.printStackTrace();
}
dirs.stream()
        .map(Paths::get)
        .flatMap(path -> {
            try {
                return Files.walk(path);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return Stream.empty();
        })
        .filter(Files::isRegularFile)
        .flatMap(path -> { 
            try {
                return Files.lines(path);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return Stream.empty();
        })
        .forEach(System.out::println);
假设您有一个
字符串的
列表
,其中包含文件的路径,如下所示:

List<String> files = Arrays.asList(
                "/test/test.txt",
                "/test2/test2.txt");
解决方案2:

您还可以使用
files.walk
以以下方式读取
/test/ehsan
目录中存在的所有文件行:

try (Stream<Path> stream = Files.walk(Paths.get("/test/ehsan"), 1)) {
    stream.filter(Files::isRegularFile)
            .flatMap(path -> {
                try {
                    return Files.lines(path);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return Stream.empty();
            })
            .forEach(System.out::println);
} catch (IOException e) {
    e.printStackTrace();
}
正如您所看到的,
文件的第二个参数。walk
指定要访问的最大目录级别数,如果您不传递它,将使用默认值,即
整数。最大值

解决方案3:

我们不要到此为止,我们可以走得更远。如果我们想读取存在于两个完全不同的目录中的所有文件行,例如
/test/ehsan
/test2/ehsan1

我们可以这样做,但我们应该谨慎,
不应该太长(因为它会降低我们程序的可读性),最好将它们分解为单独的方法,但是,因为这里不可能编写多个方法,我将在一个地方编写如何做到这一点:

假设您有一个
列表
字符串
,其中包含目录的路径,如下所示

list<String> dirs = Arrays.asList(
                "/test/ehsan",
                "/test2/ehsan1");

您确定要自己处理每一行,而不是让CSV解析库处理InputStream吗?它是否适合您的需要@你能推荐一个我可以研究的库吗?你知道Java8有多老吗?6岁;)我发现它相当可靠。这基本上是IOUtils.readLines的实现。不是我要找的。你的解决方案都考虑文件系统上的文件。我说的是SpringMultipartFile(),通常不是。我编辑了我的问题以澄清这一点。@Schlaagi我刚刚添加了可用于特殊情况的更新
list<String> dirs = Arrays.asList(
                "/test/ehsan",
                "/test2/ehsan1");
dirs.stream()
        .map(Paths::get)
        .flatMap(path -> {
            try {
                return Files.walk(path);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return Stream.empty();
        })
        .filter(Files::isRegularFile)
        .flatMap(path -> { 
            try {
                return Files.lines(path);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return Stream.empty();
        })
        .forEach(System.out::println);