gpt4 book ai didi

java - 在 Java 8 中逐行读取 Spring Multipartfile 的最佳方法

转载 作者:行者123 更新时间:2023-12-05 01:11:27 26 4
gpt4 key购买 nike

csv Spring Multipartfile 的最佳处理方式是什么?我以前用过这样的东西:

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
}

最佳答案

如果你有 InputStream,你可以使用这个:

InputStream inputStream = multipartFile.getInputStream();
new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))
.lines()
.forEach(this::handleLine);

在其他情况下:

无论是多部分文件还是有多个独立文件,在 Java 8 中使用 Stream API 都有很多方法:

解决方案一:

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

假设您有一个 StringList,其中包含如下所示的文件路径:

List<String> files = Arrays.asList(
"/test/test.txt",
"/test2/test2.txt");

然后你可以读取上面文件的所有行如下:

files.stream().map(Paths::get)
.flatMap(path -> {
try {
return Files.lines(path);
} catch (IOException e) {
e.printStackTrace();
}
return Stream.empty();
}).forEach(System.out::println);

解决方案 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();
}

如果您想递归读取/test/ehsan目录中的所有文件行,您可以这样做:

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

如您所见,Files.walk 的第二个参数指定要访问的最大目录级别数,如果您不传递它,将使用默认值,即 Integer。 MAX_VALUE

解决方案 3:

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

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

假设您有一个 StringList,其中包含您的目录路径,如下所示

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

关于java - 在 Java 8 中逐行读取 Spring Multipartfile 的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63139140/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com