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

 

Michal Zobec

Michal Zobec Senior IT Consultant, Project Manager ZOBEC Consulting