大きいファイルがアップロード出来ないときは分割するのです。（7zipで分割したファイルをPowershellで結合する）

# 3行で要約

- [7Zip](https://www.7-zip.org/)で分割、結合するのがおすすめ
- GUIの操作とコマンドでの分割方法を紹介
- コマンドやpowershellを使えば相手の環境に7zipがなくても結合可能


## はじめに

客先作業中のある日のこと

お客さん：10GB超えのフォルダを送信しようとしてるんだけど、エラーでうまく送れないんだけど、どうしたらいい？

私：分割してアップロードすればいいんじゃないですか？受け取る人に結合してもらってください。

お客さん：具体的には？

私：7zipで分割サイズ指定して圧縮できますよ。結合はコマンドプロンプトできますから、コマンドはググってください。

お客さん：えー

私：...

私：結合用のバッチファイル作るので、ファイル名教えてください。

お客さん：わーい

私：（分割ファイルとファイル結合するbatファイルを用意）

私：はい、どうぞ。分割ファイルと結合用のバッチファイルを一緒にアップロードしておいてください。


ということが先日ありました。

FD、CD-Rなどのメディアでデータの受け渡しをしていた時代はデータの分割、結合というのは頻繁に発生した作業なので専用のソフトを入れていましたが、最近はクラウドにまとめてアップロードとかしてるので、分割、結合のソフトはインストールしていません。

しかし、リモートワークが進んだことで、
・弱いサーバーにファイルをアップロードする
・細い回線で作業している人に大きいデータを送る
などでファイルの分割が必要になることがあり、まだまだ分割、結合は必要だと感じました。

今回は特殊なソフトに頼らずに結合するために、
・環境：Windows
・分割：7zip
・結合：Powershell
で、作業する方式をまとめておきます。


前提条件：分割する側の環境に7zipがインストール済であること


## ファイルの分割


### 画面で分割

1. エクスプローラーで分割したいファイル or フォルダを選択し、右クリック

2. [7-Zip] - [圧縮...]を選択する
　　![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264524/50f1aef1-1673-5713-34ff-69943e3de45f.png)

3. 起動した[圧縮]画面で、「分割ボリュームサイズ」に、サイズを指定して、OKボタンを押下で分割できます。
　　![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264524/f3832e56-f9e6-8023-5be7-fbb812773dca.png)

4. 001から連番のファイルで分割されます。


### コマンドで分割

7zに分割オプションを指定してください。


```

ダミーのファイル作成

>fsutil file createnew .\hoge 1000000000
ファイル C:\xxxx\hoge が作成されました

7zに分割オプションを指定して実行 -v1m→1MBで分割 -v1g→1GBで分割

>"C:\Program Files\7-Zip\7z.exe" a -v1m hoge.zip hoge

7-Zip 18.05 (x64) : Copyright (c) 1999-2018 Igor Pavlov : 2018-04-30

Scanning the drive:
1 file, 1000000000 bytes (954 MiB)

Creating archive: hoge.zip

Add new data to archive: 1 file, 1000000000 bytes (954 MiB)


Files read from disk: 1
Archive size: 1173575 bytes (1147 KiB)
Everything is Ok

```

001から連番のファイルで分割されます。


## ファイルの結合


展開したい環境に7zipがインストールされているなら、分割ファイルをすべて同じフォルダに配置して拡張子が001のファイルを右クリックして [7-Zip] - [ここに展開]を選択するだけで展開できます。結合作業を飛ばしていきなり展開可能です。


以下は、7zipが無い環境向けの操作方法になります。


### コマンドプロンプトでの操作

COPYコマンドで結合します。
対象ファイルを+で繋げましょう。


```

>COPY /B hoge.zip.001.+hoge.zip.002+hoge.zip.003 hoge_join.zip
hoge.zip.001
hoge.zip.002
        1 個のファイルをコピーしました。

```

hoge_join.zip が生成されるので、エクスプローラーでZipを展開できます。


### もっと便利にPowershellで

COPYコマンドだとファイル数を把握しておかないといけないので、連番のファイルを検索して自動で結合するスクリプトを作りました。

### スクリプトの作成

```powershell:join.ps1

# xxx.zip.001 からの連番のファイルで結合

$files = Get-ChildItem .\ | Where-Object { $_.Name -match '.*\.zip\.[0-9]{3}$' }

if ($files.Length -eq 0) {
    Write-Host "結合対象ファイルがありません"
    return
}

$fs = New-Object System.IO.FileStream($files[0].BaseName, 'Create')
foreach ($item in $files) {
    $data = [System.IO.File]::ReadAllBytes($item)
    $fs.Write($data, 0, $data.Length)
}
$fs.Dispose()


```

ファイル数が何個でも自動で結合する動作です。
上記の正規表現だと000も対象になるから正確ではないのですが、気にしない。
同じ連番の別ファイルがあったりしても動作しないです。

ファイル名ソートを明示的に指定するべきかもですがテスト環境では動いていました。

詰めが甘い気がするけど、レアケースに対応してコードが長くなるより、ある程度のわかりやすさを優先しました。


### スクリプトの実行

分割ファイルを同じパスにjoin.ps1を配置して以下のコマンドを実行します。

```

>powershell.exe -NoProfile -ExecutionPolicy Unrestricted .\join.ps1

```

hoge.zipが生成されるのでエクスプローラーで展開可能になります。



## おわりに

思ったより実用性ない感じかもですが。備忘録として記事に残しておきます。


### 追記

ネタ記事のつもりでしたが、意外とView数が多いみたいなので、最初に要約を追加しておきました。



# スクリプト置き場
https://github.com/part-time-penguin/qiita_powershell_samples/tree/main/11_7zip