You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Groovy脚本压缩2GB以上文件报错‘Required array length too large’求助

解决Groovy打包大文件(超过2GB)到Zip时的"Required array length too large"错误

问题出在你用zipOutput << fileInputStream这行代码上——Groovy的<<操作符会尝试把整个文件的内容一次性读取到内存中的字节数组里。当文件大小超过2GB时,所需的数组长度会超过Java中int类型的最大值(2^31-1,约2.1GB),直接触发"Required array length too large"错误。

下面是修复后的代码,改用分块读写的方式处理文件,同时优化流的资源管理:

private ZipOutputStream addZipEntry(ZipOutputStream zipOutput, File file, String path) {
    if (file.isDirectory() && !path.endsWith('/')) {
        path += "/"
    }
    logger.info("zipfile: added $path")
    ZipEntry entry = new ZipEntry(path)
    entry.time = file.lastModified()
    zipOutput.putNextEntry(entry)
    
    if (file.isFile()) {
        // 用Groovy的withInputStream自动管理流,避免手动关闭遗漏
        file.withInputStream { fis ->
            byte[] buffer = new byte[8192] // 8KB缓冲区,可根据性能需求调整大小
            int bytesRead
            while ((bytesRead = fis.read(buffer)) != -1) {
                zipOutput.write(buffer, 0, bytesRead)
            }
        }
    }
    
    zipOutput.closeEntry() // 显式关闭当前Zip条目,确保资源正确释放
    return zipOutput
}

关键修改点:

  • 替换<<操作符为分块读写:通过固定大小的缓冲区循环读取文件内容,每次只加载一小部分数据到内存,从根本上避免了大数组的创建。
  • 自动管理流资源:使用file.withInputStream替代手动创建FileInputStream,Groovy会自动在代码块执行完毕后关闭流,避免资源泄漏。
  • 显式关闭ZipEntry:添加zipOutput.closeEntry(),确保每个压缩条目正确收尾,符合Zip文件的规范。

另外,Java 7及以上版本的ZipOutputStream默认支持Zip64格式,当文件大小超过4GB或条目数过多时会自动启用,所以2GB的文件用这种方式处理完全没问题。

内容的提问来源于stack exchange,提问作者omar ahmed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 21:42:36