Java流式下载大zip文件,避免OOM内存溢出
时间: 2024-12-16 09:14:57 浏览: 2
MySQL OOM(内存溢出)的解决思路
在Java中,当你需要从网络下载大型ZIP文件并避免内存溢出(Out Of Memory,OOM)时,可以使用`InputStream`和`BufferedOutputStream`配合`ZipEntry`、`ZipOutputStream`等类逐块读取和写入数据,而不是一次性将整个文件加载到内存中。这里是一个基本的示例:
```java
import java.io.*;
import java.util.zip.*;
public class ZipStreamDownload {
private static final int BUFFER_SIZE = 4096; // 读写缓冲大小
public static void downloadAndExtractZip(String url, String destinationDir) throws IOException {
URL sourceUrl = new URL(url);
InputStream in = sourceUrl.openStream();
FileOutputStream fos = new FileOutputStream(destinationDir + "/output.zip");
BufferedOutputStream out = new BufferedOutputStream(fos, BUFFER_SIZE);
try (ZipInputStream zipIn = new ZipInputStream(in)) {
ZipEntry entry;
while ((entry = zipIn.getNextEntry()) != null) {
byte[] bytesInBuff = new byte[BUFFER_SIZE];
OutputStream currentEntryOut = new BufferedOutputStream(out, BUFFER_SIZE); // 对每个文件单独设置缓冲区
// 写入文件,直到完成
while ((bytesInBuff.length > 0) && (zipIn.read(bytesInBuff, 0, bytesInBuff.length) >= 0)) {
currentEntryOut.write(bytesInBuff, 0, zipIn.read(bytesInBuff, 0, bytesInBuff.length));
}
currentEntryOut.close(); // 关闭当前文件的输出流
zipIn.closeEntry(); // 关闭zip文件中的当前条目
}
} finally {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
if (fos != null) {
fos.close();
}
}
}
public static void main(String[] args) throws IOException {
downloadAndExtractZip("http://example.com/large_zip.zip", "download_directory/"); // 替换为你实际的URL和目标目录
}
}
```
这个例子中,我们采用了分块读取和写入的方式,每次只处理一小部分数据,从而防止了内存占用过高。当下载完成后,再对整个ZIP文件进行解压。
阅读全文