我目前正在服务层实现中开发一个方法,该方法接收一个.zip文件(文件大小可能高达600~700MB(作为Multipart文件。在该Multipart文件中压缩的所有文件中,只有4-5个我感兴趣的JSON文件,我正在使用ZipInputStream从zip中读取这些文件,并将它们存储为字符串值以供进一步使用。
服务类别:
@Async("taskExecutor")
public CompletableFuture<ResponseEntity<?>> methodname(MultipartFile file){
ZipEntry entry = null;
try(ZipInputStream zipFileStream = new ZipInputStream(file.getInputStream())){
while((entry = zipFileStream.getNextEntry) != null){
String entryName = entry.getName();
if(entryName.contains("<file1name>")){
BufferedReader br = new BufferedReader(new InputStreamReader(zipFileStream));
String value1 = br.lines().collect(Collectors.joining("n"));
zipFileStream.closeEntry();
}
if(entryName.contains("<file2name>")){
BufferedReader br = new BufferedReader(new InputStreamReader(zipFileStream));
String value2 = br.lines().collect(Collectors.joining("n"));
zipFileStream.closeEntry();
}
if(entryName.contains("<file3name>")){
BufferedReader br = new BufferedReader(new InputStreamReader(zipFileStream));
String value3 = br.lines().collect(Collectors.joining("n"));
zipFileStream.closeEntry();
}
}
}
//String value1 & String value2 merged based on some condition to finally prepare String value1.
//some logic to prepare a file
if(fileExists){
//create byte[] and Httpheaders with content disposition and mediatype and send CompletableFuture<ResponseEntity<?>>
}
}
我已经注释了方法@Async(因为我在config类中创建了一个Executor bean(,但我仍然无法弄清楚如何异步或以多线程的方式运行这些方法的不同进程,以加快处理速度。整个进程仍然在来自该执行器服务池的单个线程上运行。
有人能建议我如何在上面的方法中引入异步或多线程处理,以便像这样的并发进程吗
- 正在读取Zip文件
- 正在创建最后一个字节[]
可以更快地完成,以减少总体响应时间。
将MultipartFile存储到临时文件并尝试ZipFile
(支持流ootb(
final ZipFile zipFile = new ZipFile("dummy.zip");
zipFile
.stream()
.parallel()
.filter(entry -> entry.getName().matches("regexFile1")
|| entry.getName().matches("regexFile2")
|| entry.getName().matches("regexFile3")
)
.map(entry -> {
try {
return new EntryDto(entry.getName(), new String(zipFile.getInputStream(entry).readAllBytes(), StandardCharsets.UTF_8));
} catch (IOException e) {
throw new RuntimeException(e);
}
})
.map(dto -> {
// custom logic
return ...;
})
.collect(Collectors.toList());
dto级
class EntryDto {
private String name;
private String json;
public EntryDto(String name, String json) {
this.name = name;
this.json = json;
}
public String getName() {
return name;
}
public String getJson() {
return json;
}
}