Apache POI 密码保护大型 2GB PowerPoint 文件

问题描述 投票:0回答:1

我正在尝试使用 Apache POI 对非常大的 PPTX 文件 (2GB) 进行密码加密。如何使用 Apache POI 标准加密来加密 2GB PPTX 文件(PowerPoint 中嵌入了很多视频)?

我已经设置了

IOUtils.setByteArrayMaxOverride(Integer.MAX_VALUE);
(最大允许值),并且还尝试了其他大文件配置

ZipSecureFile.setMinInflateRatio(-1.0);
ZipInputStreamZipEntrySource.setThresholdBytesForTempFiles(50000000);
ZipPackage.setUseTempFilePackageParts(true);

无论如何,我遇到了同样的例外

Exception in thread "main" org.apache.poi.util.RecordFormatException: Can't allocate an array > 2147483647
        at org.apache.poi.util.IOUtils.safelyAllocateCheck(IOUtils.java:559)
        at org.apache.poi.util.IOUtils.safelyAllocate(IOUtils.java:547)
        at org.apache.poi.poifs.nio.ByteArrayBackedDataSource.extend(ByteArrayBackedDataSource.java:86)
        at org.apache.poi.poifs.nio.ByteArrayBackedDataSource.write(ByteArrayBackedDataSource.java:63)
        at org.apache.poi.poifs.filesystem.POIFSFileSystem.createBlockIfNeeded(POIFSFileSystem.java:493)
        at org.apache.poi.poifs.filesystem.POIFSStream$StreamBlockByteBuffer.createBlockIfNeeded(POIFSStream.java:272)
        at org.apache.poi.poifs.filesystem.POIFSStream$StreamBlockByteBuffer.write(POIFSStream.java:294)
        at org.apache.poi.poifs.filesystem.DocumentOutputStream.write(DocumentOutputStream.java:144)
        at org.apache.poi.poifs.filesystem.DocumentOutputStream.write(DocumentOutputStream.java:124)
        at java.base/java.io.FilterOutputStream.write(FilterOutputStream.java:87)
        at java.base/java.io.FilterOutputStream.write(FilterOutputStream.java:137)
        at org.apache.poi.util.LittleEndianOutputStream.write(LittleEndianOutputStream.java:89)
        at org.apache.poi.util.IOUtils.copy(IOUtils.java:410)
        at org.apache.poi.util.IOUtils.copy(IOUtils.java:387)
        at org.apache.poi.poifs.crypt.standard.StandardEncryptor$StandardCipherOutputStream.processPOIFSWriterEvent(StandardEncryptor.java:201)
        at org.apache.poi.poifs.filesystem.POIFSDocument.<init>(POIFSDocument.java:112)
        at org.apache.poi.poifs.filesystem.DirectoryNode.createDocument(DirectoryNode.java:380)
        at org.apache.poi.poifs.crypt.standard.StandardEncryptor$StandardCipherOutputStream.writeToPOIFS(StandardEncryptor.java:185)
        at org.apache.poi.poifs.crypt.standard.StandardEncryptor$StandardCipherOutputStream.close(StandardEncryptor.java:175)
        at Program.encryptPPTXFile(Program.java:108)

这是我的代码:

try(POIFSFileSystem fs = new POIFSFileSystem()) {
    EncryptionInfo info = new EncryptionInfo(EncryptionMode.standard);
    Encryptor encryptor = info.getEncryptor();
    encryptor.confirmPassword(password);

    // Read in an existing OOXML file and write to encrypted output stream
    try (OPCPackage opc = OPCPackage.open(inputPath);
        OutputStream os = encryptor.getDataStream(fs)) {
        opc.save(os);
    }

    // Write out the encrypted version
    try (FileOutputStream fos = new FileOutputStream(outputPath)) {
        fs.writeFilesystem(fos);
    }

    System.out.println("Document successfully encrypted");

} catch (IOException | GeneralSecurityException | InvalidFormatException e) {
    e.printStackTrace();
}
java apache-poi
1个回答
0
投票

POI 5.2.3 有 TempFilePOIFSFileSystem - POIFSFileSystem 的子类。加密非常大的文件时应使用 TempFilePOIFSFileSystem。 POIFSFileSystem 使用字节数组来处理数据,这只能处理 2Gb 的解压数据。

© www.soinside.com 2019 - 2024. All rights reserved.