Sch*_*agi 2 java spring java-8
什么是最好的处理 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
}
Run Code Online (Sandbox Code Playgroud)
据我所知,在处理它之前,这首先将整个文件加载到内存中的一个列表中,对于具有数十万行的文件,这可能需要相当长的时间。
有没有办法逐行处理它而无需手动实现迭代的开销(即使用诸如read(), hasNext(), ... 之类的东西?我正在为文件系统中的文件寻找类似于此示例的简洁内容:
try (Stream<String> stream = Files.lines(Paths.get("file.csv"))) {
stream.forEach(this::handleLine);
} catch (IOException e) {
// handle exception
}
Run Code Online (Sandbox Code Playgroud)
如果你有 InputStream,你可以使用这个:
InputStream inputStream = multipartFile.getInputStream();
new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))
.lines()
.forEach(this::handleLine);
Run Code Online (Sandbox Code Playgroud)
在其他情况下:
无论是多部分文件还是您有多个独立文件,在 Java 8 中使用StreamAPI有很多方法可以做到:
解决方案1:
如果您的文件位于不同的目录中,您可以这样做:
想象一下,你有一个List中String包含了像下面的文件路径:
List<String> files = Arrays.asList(
"/test/test.txt",
"/test2/test2.txt");
Run Code Online (Sandbox Code Playgroud)
然后您可以阅读上述文件的所有行,如下所示:
files.stream().map(Paths::get)
.flatMap(path -> {
try {
return Files.lines(path);
} catch (IOException e) {
e.printStackTrace();
}
return Stream.empty();
}).forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)
解决方案2:
您还可以/test/ehsan使用Files.walk以下方式读取目录中存在的所有文件行:
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();
}
Run Code Online (Sandbox Code Playgroud)
如果你想递归地读取/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();
}
Run Code Online (Sandbox Code Playgroud)
如您所见,第二个参数Files.walk指定要访问的最大目录级别数,如果您不传递它,则将使用默认值,即Integer.MAX_VALUE.
解决方案3:
让我们不要停在这里,我们可以走得更远。如果我们想读取存在于两个完全不同目录中的所有文件行,例如/test/ehsan和/test2/ehsan1怎么办?
可以做但是要慎重,Stream不要太长(因为会降低我们程序的可读性)最好把它们分成不同的方法,但是因为这里不能写多个方法,所以我会写进去一个地方如何做到这一点:
想象一下,你有一个List的String包含您的目录,如下面的路径
list<String> dirs = Arrays.asList(
"/test/ehsan",
"/test2/ehsan1");
Run Code Online (Sandbox Code Playgroud)
然后我们可以这样做:
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);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3563 次 |
| 最近记录: |