PowerShell: Commandlet Compress-Archive neumí vytvářet archivy větší než 2 GB – Chyba: „Stream was too long“
Při práci s balíčky si chci zjednodušit život, a proto si archivuji balíčky jako „release“ (vydání) v podobě ZIP archivu. Protože tuto akci velmi často opakuji, po čase jsem se rozhodl ji automatizovat. Před týdnem jsem se setkal se zajímavou chybou při vytváření archivů větších než 2 GB.
Pro kompresi používám commandlet Compress-Archive, vše několik let fungovalo bez problémů. Nedávno jsem se setkal s chybou
Stream was too long
kterou hlásí přímo commandlet Compress-Archive.
Protože se problém začal opakovat, začal jsem řešit čím je chyba způsobena. Moje překvapení bylo, když jsem zjistil, že je to skutečná chyba na straně Microsoftu v PowerShellu u tohoto commandletu. Nejedná se však chybu přímo v PowerShellu, ale o omezení na úrovni .NET Framework.
Omezení commandlet Compress-Archive a .NET Framework
O co jde? Oficiální dokumentace říká
anglicky
The Compress-Archive cmdlet uses the Microsoft .NET API System.IO.Compression.ZipArchive to compress files. The maximum file size is 2 GB because there’s a limitation of the underlying API.
česky
Commandlet Compress-Archive používá Microsoft .NET funkci API System.IO.Compression.ZipArchive pro kompresi souborů. Maximální velikost souboru jsou 2 GB protože se jedná o omezení na úrovni API, která tuto funkci používá.
Problém je znám delší dobu, 4 roky. Je však o něco komplikovanější, protože kromě omezení API samotného, které řeší nová funkce Zip64, je zde problém s implementací a pamětí alokovanou pro zápis a čtení během operace se soubory. Zdá se tedy že řešení je v nedohlednu.
Commandlet 7Zip4Powershell
Jak z toho ven? Alternativou může být použití commandletu 7Zip4Powershell, který skrze API využívá kompresní opensource nástroj 7-ZIP.
Odkazy
- PowerShell Open Source – Compress-Archive not working (anglicky)
- Add support for Zip64 for archives > 4GB (anglicky)
- 7Zip4Powershell (anglicky)