我目前正在使用 Apache POI 创建一个 excel 文件。我想通过分段上传将此文件发送到 AWS S3 。我使用SXSSFWorkbook与所使用的替代技术相结合BigGridDemo以创建文档本身和发送的纸张数据。这就是它变得有点棘手的地方。我有一些主要工作,但由于NULs 被写入组成工作表数据的 XML 文件,我生成了一个无效的 excel 文件。在试图追查发生这种情况的原因时,我偶然发现了这一点:import java.io._import java.util.zip._val bo = new ByteArrayOutputStream()val zo = new ZipOutputStream(bo)zo.putNextEntry(new ZipEntry("1"))zo.write("hello".getBytes())zo.write("\nhello".getBytes())val bytes1 = bo.toByteArray()// bytes1: Array[Byte] = Array(80, 75, 3, 4, 20, 0, 8, 8, 8, 0, 107, -121, -9, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 49)bo.reset()zo.write("hello".getBytes())val bytes2 = bo.toByteArray() // bytes2: Array[Byte] = Array()zo.flush()val bytes2 = bo.toByteArray() // bytes2: Array[Byte] = Array()bo.size //res11: Int = 0zo.putNextEntry() // If I make a new entry it works but I can't do this in real code...bo.size // res17: Int = 66似乎当我重置底层字节输出流时,它会导致 ZipOutputStream 记录任何内容。这让我很惊讶,所以我查看了 ZipOutputStream的底层源代码。我注意到默认方法是 DEFLATED,它只是调用DeflaterOutputStream#write,然后我查看了 deflater 代码本身,认为压缩算法中可能有一些我不明白的更深层次的东西,需要不重置流,或者是以某种方式受到它的影响。我找到了对FULL_FLUSH的引用并指出如果先前的压缩数据已损坏或需要随机访问,则压缩状态将被重置,以便处理压缩输出数据的充气器可以从该点重新启动。这对我来说听起来不错,因为我可以想象重置字节流可能会被视为损坏的数据。所以我重复了我的最小实验:import java.io._import java.util.zip._val bo = new ByteArrayOutputStream()val zo = new ZipOutputStream(bo)zo.setLevel(Deflater.FULL_FLUSH)zo.putNextEntry(new ZipEntry("1"))zo.write("hello".getBytes())val bytes1 = bo.toByteArray()// bytes1: Array[Byte] = Array(80, 75, 3, 4, 20, 0, 8, 8, 8, 0, 84, 75, -8, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 49)zo.flush()bo.reset()zo.write("\nhello".getBytes())zo.flush()val bytes2 = bo.toByteArray() // bytes2: Array[Byte] = Array()所以没有骰子。我的目标是将所有内容(因此是字节数组)保留在内存中,并通过删除我已经写入 UploadPartRequest 的字节来保持内存压力较低,但这确实给事情带来了麻烦,因为我的印象是XML 文件必须压缩,因为 Excel 文件格式实际上是一个 zip 文件。我的完整代码显然有点复杂,并且使用了Play 框架和 Scala 2.12.6,我已经把它放在 github 上,如果你想查看或运行它,还添加了一些额外的注释。
添加回答
举报
0/150
提交
取消