Windowsで巨大ファイルを含むフォルダをZIP(無圧縮)に格納する方法

Windowsで巨大ファイルを含むフォルダをZIP(無圧縮)に格納する方法

こんにちは!

複数の大容量のファイルを含むフォルダをバックアップやアーカイブする際、ZIPファイルに格納することがよくあります。

しかし、既に圧縮済みのファイル(動画、画像、PDFなど)を再圧縮すると、処理時間がかかる割に圧縮効果が少かったり、圧縮にものすごく時間がかかってしまうことがあります。別に容量を制限したいわけでなく、単に複数のファイルを単にひとまとめにしたいときには「無圧縮ZIP」(ストアモード)が1つの選択肢となります。

この記事では、特に巨大ファイル(数GB〜数十GB)を含むフォルダを無圧縮ZIPに格納する方法について解説します。

Windows標準機能の限界

Windows Explorerの標準ZIP機能では、ファイルを右クリックして「送る」→「圧縮(zip形式)フォルダー」を選択できますが、これには2つの問題があります

  1. 無圧縮(ストアモード)を選択するオプションがない
  2. いちいち圧縮してしまうので大容量ファイルの処理に時間がかかる

PowerShellの無圧縮ZIPコマンドと制限

PowerShellにはCompress-Archiveコマンドレットがあり、-CompressionLevel NoCompressionオプションで無圧縮ZIPを作成できます。

Compress-Archive -Path "C:\example_backup" -DestinationPath "C:\temp\example_backup.zip" -CompressionLevel NoCompression

しかし、このコマンドには制限があるんです

  • 最大ファイルサイズは2GBまで(Microsoft .NET APIの制限による)
  • 実際には20GB程度のフォルダサイズでエラーが発生することが多い

実際のエラーメッセージ例

大きなファイルを含むフォルダで実行すると、以下のようなエラーが発生します

"3" 個の引数を指定して "Write" を呼び出し中に例外が発生しました: "ストリームが長すぎます。"
発生場所 C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Archive\Microsoft.PowerShell.Archive.psm1:820 文字:29
+ ...                     $destStream.Write($buffer, 0, $numberOfBytesRead)
+                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : IOException

権限が制限されている場所に出力しようとすると、以下のエラーが発生することもあります

New-Object : "2" 個の引数を指定して ".ctor" を呼び出し中に例外が発生しました: "パス 'C:\example_backup.zip' へのアクセスが拒否されました。"
発生場所 C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Archive\Microsoft.PowerShell.Archive.psm1:729 文字:30
+ ... ileStream = New-Object -TypeName System.IO.FileStream -ArgumentList $ ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [New-Object]、MethodInvocationException
    + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand

つまり、PowerShellのCompress-Archiveは小〜中規模のファイルには便利ですが、巨大ファイルには適していないんです。

ていうか、いちいち個別ファイルのサイズなんて気にせずZIPにしたいですよね

7-Zipを使った解決策

そんなときはやっぱり最強のzipソフトウェア「7-Zip」の出番となります。
これはオープンソースの高性能圧縮・解凍ソフトウェアで、素晴らしいです。

  • 無圧縮(ストアモード)での保存が可能
  • ファイルサイズの制限が実質的にない(50GB以上のファイルも処理可能)
  • コマンドラインからの操作が可能
  • 様々な圧縮形式に対応

Chocolateyを使った7-Zipのインストール方法

さて、では、7-Zipをコマンドラインでインストールしましょう。私はChocolateyというWindows版のaptのようなパッケージマネージャをつかってます。
コマンドラインから簡単に7-Zipをインストールできます。

1. Chocolateyのインストール(まだインストールされていない場合)

PowerShellを管理者権限で開き、以下のコマンドを実行します:

Set-ExecutionPolicy Bypass -Scope Process -Force
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))

2. 7-Zipのインストール

Chocolateyがインストールされたら、
ひきつづき Powershellの管理者権限で、以下のコマンドで7-Zipをインストールします

choco install 7zip -y

-yオプションは、確認プロンプトに自動的に「はい」と回答します。

7-Zipを使った無圧縮ZIPの作成手順

さて実際に7-Zipを使って無圧縮ZIPを作成していきましょう

例として、C:\example_backupフォルダを無圧縮ZIPに格納します。

PowerShellでの実行手順

  1. PowerShellを開きます(管理者権限は不要です)
  2. 以下のコマンドをPoweshellにペタっとしましょう
$7zipPath = "C:\Program Files\7-Zip\7z.exe"
& $7zipPath a -tzip -mx0 "C:\temp\example_backup.zip" "C:\example_backup\*"

このコマンドの説明

  • a: アーカイブに追加するコマンド
  • -tzip: ZIP形式を指定
  • -mx0: 無圧縮(ストアモード)を指定
  • 最初のパスは出力先のZIPファイル
  • 2番目のパスは圧縮するフォルダ内のすべてのファイル
  1. 処理が完了するまで待ちます(大容量ファイルの場合は時間がかかります)

まとめ

巨大ファイルを含むフォルダを無圧縮ZIPに格納するには

  1. Windows標準のZIP機能は無圧縮オプションがなく不向き
  2. PowerShellのCompress-Archiveは2GB以上のファイルで問題が発生
  3. 7-Zipが最適な解決策(Chocolateyでのインストールが簡単)
  4. 7-Zipのコマンドライン(-mx0オプション)で無圧縮ZIPを作成可能

Windowsで巨大ファイルをふくむフォルダのZIP化は7-Zipにおまかせ!ですね

Read more

Raspberry Pi 5のWebサーバーをインターネットに公開する。ポートは開けない、WireCanalのトンネルで

Raspberry Pi 5のWebサーバーをインターネットに公開する。ポートは開けない、WireCanalのトンネルで

受信ポートを閉じたまま、Raspberry Pi 5のWebサーバーをインターネットに公開します。WireCanalのAgentをワンライナーで入れ、canalを作り、systemdで常駐化。ポート開放もルーター設定も不要で、操作はおよそ5分。再起動後の自動復活まで実測で検収しました。

By Qualiteg プロダクト開発部
Raspberry Pi 5を堅牢化する。SSH鍵認証・UFW・fail2banと、再起動でIPv6が復活する罠

Raspberry Pi 5を堅牢化する。SSH鍵認証・UFW・fail2banと、再起動でIPv6が復活する罠

セットアップ直後のRaspberry Pi 5は、パスワード認証が有効なまま、ファイアウォールなし、更新可能なパッケージ172件と無防備です。SSHの鍵認証化・UFW・fail2ban・自動更新・IPv6無効化を実コマンドと実測検収で解説します。sysctlのIPv6無効化が再起動で復活する現象と恒久対策も実機で確認しました。

By Qualiteg プロダクト開発部
LINE Botをローカルで開発する。WebhookのURLが毎回変わる問題を固定URLで解決する

LINE Botをローカルで開発する。WebhookのURLが毎回変わる問題を固定URLで解決する

こんにちは! LINE Botを作ろうとして最初にぶつかる壁は、コードではなくWebhookです。 LINEのMessaging APIは、ユーザーがBotに送ったメッセージを、LINEのサーバーからこちらのサーバーへHTTPSのPOSTで通知してきます。 この受け口(Webhook URL)にはインターネットから届くHTTPSのURLしか指定できず、開発中の http://localhost:5000 をそのまま書くことはできません。 トンネルツールで一時URLを発行して回避する方法が定番ですが、今度は別の問題が待っています。トンネルの方式によっては、起動のたびにランダムなURLが発行されます。その場合、開発を再開するたびにLINE Developersコンソールを開いてWebhook URLを書き換えることになります。コードを直すたび、翌日再開するたび、まずURLの貼り直しから。これが地味に堪えます。 結論から言うと、 ローカルPCの開発サーバーに「変わらない公開URL」を1本付けてしまえば、Webhook URLの設定は最初の1回だけで終わります。 この記事では、L

By Qualiteg プロダクト開発部