我使用下面的代码生成zip文件并将其返回到前端,当文件很小时,性能是正常的。但是,当压缩文件超过1GB时,下载的文件将被破坏,压缩文件的数量也会减少,而且这种现象并不总是发生,有时下载3.2GB文件是正常的,=_=
期待着听到大家的来信
outputStream = response.getOutputStream();
ZipOutputStream zipOutStream = null;
FileInputStream filenputStream = null;
BufferedInputStream bis = null;
try {
zipOutStream = new ZipOutputStream(new BufferedOutputStream(outputStream));
zipOutStream.setMethod(ZipOutputStream.DEFLATED);
for (int i = 0; i < files.size(); i++) {
File file = files.get(i);
filenputStream = new FileInputStream(file);
bis = new BufferedInputStream(filenputStream);
zipOutStream.putNextEntry(new ZipEntry(fileName[i]));
int len = 0;
byte[] bs = new byte[40];
while ((len = bis.read(bs)) != -1) {
zipOutStream.write(bs,0,len);
}
bis.close();
filenputStream.close();
zipOutStream.closeEntry();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(Objects.nonNull(filenputStream)) {
filenputStream.close();
}
if(Objects.nonNull(bis)) {
bis.close();
}
if (Objects.nonNull(zipOutStream)) {
zipOutStream.flush();
zipOutStream.close();
}
if (Objects.nonNull(outputStream)) {
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}发布于 2022-05-20 03:00:25
您的代码可能存在的问题之一是内存泄漏和流,如果代码运行到任何异常时,内存泄漏和流不会被正确刷新和关闭。
一种帮助减少这些泄漏和确保所有资源被正确关闭的方法,即使在出现异常的情况下,也是使用试探性资源。
下面是一个示例,说明如何重写代码示例以利用试用资源。
在这个例子中,为了让它在独立的IDE环境中编译,我把它放在一个名为testStream的函数中,因为我不知道参数files和fileName的来源是什么。因此,这两个参数的验证和内容都是偶然的,假设它们都有相同数目的条目,并且彼此配对(每个元素0被配对在一起)。由于这种奇怪的关系存在,它由名为i的变量链接,以反映原始源代码。
public void testStream( HttpServletResponse response, List<File> files, String[] fileName )
{
int i = 0;
try (
ServletOutputStream outputStream = response.getOutputStream();
ZipOutputStream zipOutStream = new ZipOutputStream( new BufferedOutputStream( outputStream ) );
)
{
zipOutStream.setMethod( ZipOutputStream.DEFLATED );
for ( File file : files )
{
try (
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream( file ) );
) {
zipOutStream.putNextEntry( new ZipEntry( fileName[i++] ) );
int len = 0;
byte[] bs = new byte[4096];
while ( (len = bis.read( bs )) != -1 )
{
zipOutStream.write( bs, 0, len );
}
// optional since putNextEntry will auto-close open entries:
zipOutStream.closeEntry();
}
}
}
catch ( IOException e )
{
e.printStackTrace();
}
}这是成功的编译,应该可以工作;但是可能需要一些其他的调整才能使它在您的环境中与您的数据一起工作。希望它能消除关闭流和其他资源时可能遇到的问题。
https://stackoverflow.com/questions/72312853
复制相似问题