Edit: to those marking this as a duplicate, this has nothing (directly) to do with array limits. This has to do with the Apache POI libraries not currently being capable of handling larger files.
I've used apache POI to generate an XLSX file that is about 6GB. The file works perfectly fine when I open it in Excel. I'm now trying to add encryption when I generate the file, but I'm running into error with any file greater than 2GB (files less than 2GB encrypt fine and are also openable in Excel)
org.apache.poi.util.RecordFormatException: Can't allocate an array > 2147483647
at org.apache.poi.util.IOUtils.safelyAllocate(IOUtils.java:545)
at org.apache.poi.poifs.nio.ByteArrayBackedDataSource.extend(ByteArrayBackedDataSource.java:85)
at org.apache.poi.poifs.nio.ByteArrayBackedDataSource.write(ByteArrayBackedDataSource.java:62)
at org.apache.poi.poifs.filesystem.POIFSFileSystem.createBlockIfNeeded(POIFSFileSystem.java:453)
at org.apache.poi.poifs.filesystem.POIFSStream$StreamBlockByteBuffer.createBlockIfNeeded(POIFSStream.java:223)
at org.apache.poi.poifs.filesystem.POIFSStream$StreamBlockByteBuffer.write(POIFSStream.java:245)
at org.apache.poi.poifs.filesystem.DocumentOutputStream.write(DocumentOutputStream.java:144)
at org.apache.poi.util.IOUtils.copy(IOUtils.java:402)
at org.apache.poi.poifs.crypt.ChunkedCipherOutputStream$EncryptedPackageWriter.processPOIFSWriterEvent(ChunkedCipherOutputStream.java:299)
at org.apache.poi.poifs.filesystem.POIFSDocument.<init>(POIFSDocument.java:117)
at org.apache.poi.poifs.filesystem.DirectoryNode.createDocument(DirectoryNode.java:373)
at org.apache.poi.poifs.crypt.ChunkedCipherOutputStream.close(ChunkedCipherOutputStream.java:250)
.....
The code I'm using to encrypt the file is:
public static void encryptFile(File unencryptedFile, File outputFile, String password) throws IOException, InvalidFormatException, GeneralSecurityException
{
POIFSFileSystem fs = new POIFSFileSystem();
EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile);
Encryptor enc = info.getEncryptor();
enc.confirmPassword(password);
try(OPCPackage opc = OPCPackage.open(unencryptedFile))
{
try(OutputStream os = enc.getDataStream(fs))
{
opc.save(os);
} <-----EXCEPTION IS THROWN HERE BY THE CALL TO close()
}
try(FileOutputStream fos = new FileOutputStream(outputFile))
{
fs.writeFilesystem(fos);
}
}
The exception is getting throw by the close() when this try block exits (as noted in the code above). Does anyone know another method I can use to encrypt the file that isn't limited to 2GB?