先日、pixivFANBOX にファイルをアップロードしようとしたら 1 ファイル 300 MB までの制限に引っかかってしまいました。
というわけでファイルを分割してアップロードしたり、ユーザさんに手元で結合してから解凍してもらったりしなければなりません。しかし、macOS に付属のアーカイブユーティリティは分割された ZIP ファイルの解凍に対応していません。サードパーティ製のアーカイバにはその機能が付いていたりすることもありますが、出来ればそういう余計なものをインストールせずに使ってもらいたいのでファイルサイズの大きなファイルを分割して pixivFANBOX や BOOTH にアップロードする方法を考えてみました。
pixivFANBOX のアップローダについて
「300 MB」ってどういうサイズなのか
試してみたところ 314,572,800(2^20*3
)バイトではなく 300,000,000(10^6*300
)バイトでした。1 バイトでも超えるとアップロードする前にブラウザに拒否されます。
2019年2月時点でアップロード方法の拡充を検討していたようですが現時点では変化は無い気がします。ストレージや帯域の確保なども大変でしょうからなかなか難しいのではないかと思います。
しめなわんさん、おはようございます。貴重なご意見をありがとうございます。アップロード方法の拡充について、より便利にお使いいただけるよう実装を検討しております。恐れ入りますが、実装まで今しばらくお待ちください。今後ともpixivFANBOXをどうぞよろしくお願い致します。
— pixivFANBOX公式 (@pixivFANBOX) February 22, 2019
BOOTH では 1 GB まで対応しているようです。比較的大きなサイズではありますがゲームや映像作品だと超えてしまうことがありそうな気がします。
pixivFANBOX のアップローダは拡張子偽装不可
何らかの方法でファイルを分割したとしてそれがアップロード可能な形式ではない場合、例えば拡張子を .zip
や .txt
に変えてしまえばとりあえず pixivFANBOX 側に送ることは出来ますがファイルタイプをチェックしているようなのでエラーになってしまうようです。
話が長くなってしまうので先にまとめを書く
pixivFANBOX にアップロード可能な形式で汎用性が高い形式は「ZIP」だと思います。ZIP には分割する機能があるのでこれを用いるのが簡単なのですが、分割された ZIP ファイルは最初のファイル以外はヘッダの違いからか pixiv 側で ZIP ファイルだと認められないことがあります(分割方法によります)。
従って、pixivFANBOX に分割したファイルをアップロードする場合は下記のような工程になると思われます。
- フォルダを1つの ZIP ファイルにする(ファイルの場合は不要)
- 1 ファイル 300 MB 以内で分割する
- 各ファイルを ZIP ファイルにする
Windows はユーティリティが豊富なので BOOTH の回答にある通り 7-Zip 等で対応出来ると思います(7-Zip で分割 ZIP 作っても2つ目以降はエラーになる気がしますが)。
後述しますが Linux や macOS でもコマンドを扱えれば別途アプリケーションを用意せずとも分割や結合を行うことは可能です。しかし、特に macOS をお使いの方はコマンドに馴染みが無いと思いますので毎回コマンドを叩くのは大変だと思います。macOS には Automator というアプリケーションがあるので分割・結合用の自作アプリケーションかサービスを作るのが良いと思います。例えば下記の構成で 1 ファイル 300 MB 以内のファイルを生成するアプリケーションを作ることが出来ます。
「よくわからない!」と言う方は「分割ちゃん.app」と「結合ちゃん.app」を作って pixivFANBOX で頒布してますのでそちらをご自由にお使いください。
分割アプリケーションサンプル
シェルは「/bin/bash」または「/bin/ksh」、入力の引き渡し方法は「引数として」に設定します。limit
変数の値を増やしてもらえば BOOTH 用にも使えるかもしれません(BOOTH にアップする 1 GB を超えるファイルが無いので未検証)。
set -e set -u PATH=/usr/bin:/bin limit=$((10**6*300-1024)) split_and_zip(){ split -b ${limit} -a 1 "${1}" "${1}". for p in "${1}".? do zip -q -0 -m -T "${p}".zip "${p}" done } for f do basename=$(basename "${f}") dirname=$(dirname "${f}") type=$(stat -f %T "${f}") cd "${dirname}" case ${type} in /) zip -q -r -y "${basename}".zip "${basename}" split_and_zip "${basename}".zip ;; '') split_and_zip "${basename}" ;; esac done
結合アプリケーションサンプル
シェルは「/bin/bash」または「/bin/ksh」、入力の引き渡し方法は「引数として」に設定します。
set -e set -u PATH=/usr/bin:/bin cd "$(dirname "${1}")" for f do unzip -q "${f}" done cat "${@%.*}" >"${1%.?.*}"
分割ちゃん.appと結合ちゃん.app
分割ちゃん.app
サイズの大きなファイルを 300 MB 毎の ZIP ファイルに分割するアプリケーションです。26 分割まで対応しているので約 7.8 GB までのファイルであれば pixivFANBOX にアップロード可能な形式で 300 MB 毎に分割された ZIP ファイルを作成することが出来ます。
実行するとファイル選択ダイアログが開くので分割したいファイルやフォルダを選択します。暫くすると選択したファイルと同じフォルダに分割された ZIP ファイルが作成されます。
分割が終わると通知で教えてくれます。
pixivFANBOX や BOOTH には .a.zip
や .b.zip
という名前のファイルをアップロードします。
結合ちゃん.app
分割ちゃん.app で分割された ZIP ファイルを結合して 1 つの ZIP ファイルにするアプリケーションです。
実行するとファイル選択ダイアログが開くので結合したいファイルを選択します。暫くすると選択したファイルと同じフォルダに結合された ZIP ファイルが作成されます。アプリケーション内でファイルの並び替えを行うので選択する順番は自由で構いません。
結合が終わると通知で教えてくれます。
結合されたファイルは Finder やアーカイブユーティリティから解凍することが出来ます。
コマンドでなんとかする
zip コマンドによる分割を試す
zip
コマンドでは -s サイズ
オプションで分割 ZIP を作成することが出来ます。
300 MB 毎に分割された ZIP を作成する例
分割サイズの指定には byte 指定出来ないので k
を使って 300000000 / 1024
の結果(292968k
)をオプションに渡します。
zip -r -y -s $((300*10**6/1024))k EasyWine.app.zip EasyWine.app
$ ls total 639664 drwxr-xr-x 3 501 0 96 11 22 20:21 EasyWine64.app -rw-r--r-- 1 501 0 299999232 11 24 03:55 EasyWine64.app.z01 -rw-r--r-- 1 501 0 24163798 11 24 03:55 EasyWine64.app.zip $ file EasyWine64.app.z* EasyWine64.app.z01: Zip multi-volume archive data, at least PKZIP v2.50 to extract EasyWine64.app.zip: Zip archive data
しかし、pixivFANBOX ではアップロード可能なファイルの拡張子に制限があるため .z01
のようなファイルは選択することが出来ません。
.z01
のファイルに .zip
を追加して .z01.zip
のようにリネームすればアップロードすることは可能でしたが、.z01
を .z01.zip
にリネームしてしまっているので解凍の際にファイルを見失ってしまいます。そのため、ユーザには .z01.zip
のようなファイルだけ .z01
にリネームしてもらい、ターミナルで解凍してもらう…という流れになります。
アーカイブユーティリティは分割された ZIP を解凍出来ないようです。
解凍は「分割されたファイルを分割サイズ 0
(ゼロ)にする」という感じのちょっとわかりにくいコマンドになります。.z01
などのファイルを指定する必要はありません。--out ファイル名
のファイル名は任意です。
zip -s 0 EasyWine64.app.zip --out unsplit.zip
$ ls total 1288016 -rw-r--r-- 1 501 0 299999232 11 24 03:55 EasyWine64.app.z01 -rw-r--r-- 1 501 0 24163798 11 24 03:55 EasyWine64.app.zip -rw-r--r-- 1 501 0 324163026 11 24 04:10 unsplit.zip
結合されたファイルを解凍します。
unzip unsplit.zip
アーカイブユーティリティが .z01
などのファイルを見つけてくれるならいいんですがそれも無理なので微妙ですね。
zipsplit コマンドによる分割を試す
zipsplit
コマンドに ZIP ファイルを渡すことで分割された ZIP ファイルを作成することもできます。このコマンドでは ZIP ファイルの中身を上手くやりくりして最大サイズに収まるように分けて個別の ZIP ファイルとして生成してくれるようです。この仕組の都合上、圧縮ファイル内に最大サイズを超えるファイルが存在する場合は ZIP を分割することは出来ません。また、2 GB を超えるファイルをサポートしていません。
分割元の ZIP ファイルを作成しておきます。
$ ls total 657024 drwxr-xr-x 3 501 0 96 11 22 20:21 EasyWine64.app -rw-r--r-- 1 501 0 324163026 11 24 04:24 EasyWine64.app.zip
最大サイズを 300 MB に設定して ZIP ファイルを分割します。
zipsplit -n $((300*10**6)) EasyWine64.app.zip
分割された ZIP ファイルは名前が変わってしまうようです。
$ ls total 1307296 -rw-r--r-- 1 501 0 296834141 11 24 04:25 EasyWin1.zip -rw-r--r-- 1 501 0 27328907 11 24 04:25 EasyWin2.zip drwxr-xr-x 3 501 0 96 11 22 20:21 EasyWine64.app -rw-r--r-- 1 501 0 324163026 11 24 04:24 EasyWine64.app.zip
zipsplit
コマンドを使った場合の特徴としてそれぞれの ZIP ファイルが ZIP ファイルとして独立している点です。「複数のフォルダに分けて圧縮したので解凍するときにひとつに集約すれば元通りになる」という感じ。「結合」と言うよりは「統合」かもしれません。
unzip EasyWin1.zip unzip EasyWin2.zip
split コマンドによる分割を試す
テキストファイルを指定行数で分割したりするのに使う split
コマンドにはバイトサイズに対応した分割モードがあるのでこちらを使います。
ひとまず圧縮済みの ZIP ファイルを最大サイズ 300 MB で分割してみます。
split -b $((300*10**6)) -a 1 EasyWine64.app.zip EasyWine64.app.zip.
300 MB ピッタリで分割することが出来ました。
$ ls total 1312480 drwxr-xr-x 3 501 0 96 11 22 20:21 EasyWine64.app -rw-r--r-- 1 501 0 324163026 11 24 04:24 EasyWine64.app.zip -rw-r--r-- 1 501 0 300000000 11 24 04:36 EasyWine64.app.zip.a -rw-r--r-- 1 501 0 24163026 11 24 04:36 EasyWine64.app.zip.b
しかしこれだと ZIP のヘッダが入ると 300 MB をわずかに超えてしまうので 1 KB くらい減らして作り直します。
$ split -b $((300*10**6-1024)) -a 1 EasyWine64.app.zip EasyWine64.app.zip. $ ls total 1297848 drwxr-xr-x 3 501 0 96 11 22 20:21 EasyWine64.app -rw-r--r-- 1 501 0 324163026 11 24 04:24 EasyWine64.app.zip -rw-r--r-- 1 501 0 299998976 11 24 04:41 EasyWine64.app.zip.a -rw-r--r-- 1 501 0 24164050 11 24 04:41 EasyWine64.app.zip.b
このファイルに .zip
という拡張子を追加すればアップロード可能ファイルとして選択することは可能ですが、ZIP ファイルを単純に分割しただけなので最初のファイル以外はエラーが発生してしまいます。この状態になるとこの投稿は公開することが出来なくなり、最初からやり直しになってしまいます。
面倒ですがそれぞれを再度 ZIP にします。既に圧縮をしているためここでは -0
を指定して無圧縮 ZIP にすることで圧縮・解凍にかかるコストを減らします。
zip -0 EasyWine64.app.zip.a.zip EasyWine64.app.zip.a zip -0 EasyWine64.app.zip.b.zip EasyWine64.app.zip.b
total 1940376 drwxr-xr-x 3 501 0 96 11 22 20:21 EasyWine64.app -rw-r--r-- 1 501 0 324163026 11 24 04:24 EasyWine64.app.zip -rw-r--r-- 1 501 0 299998976 11 24 04:54 EasyWine64.app.zip.a -rw-r--r-- 1 501 0 299999166 11 24 04:55 EasyWine64.app.zip.a.zip -rw-r--r-- 1 501 0 24164050 11 24 04:54 EasyWine64.app.zip.b -rw-r--r-- 1 501 0 24164240 11 24 04:55 EasyWine64.app.zip.b.zip
出来上がった ZIP ファイルは正常に pixivFANBOX にアップロード出来ます。
解凍はそれぞれの ZIP ファイルを1段階解凍した後に結合して出来上がったファイルを再度解凍します。
最初に分割されたファイルを解凍します。この操作は Finder でも行うことが出来ます。
unzip EasyWine64.app.zip.a.zip unzip EasyWine64.app.zip.b.zip
次に、cat
コマンドでファイルを結合します。ファイルが複数ある場合は *
や ?
などのワイルドカードを使用した方が楽です。また、結合の順番を間違えることもありません。
cat EasyWine64.app.zip.? >EasyWine64.app.zip
最後に出来上がった ZIP ファイルを解凍します。この操作は Finder で行うことが出来ます。
unzip EasyWine64.app.zip
7z コマンドによる分割を試す
7z
コマンドは Homebrew や MacPorts で p7zip
をインストールすることで使えるようになります。
分割サイズを 300 MB からちょっと削った値にして分割圧縮します。こちらも拡張子制限によりアップロードは出来ませんし、.zip
を追加してもエラーになります。
$ 7z a -v$((300*10**6-1024)) EasyWine.app.zip EasyWine.app $ ls total 626704 drwxr-xr-x 3 501 0 96 11 22 20:21 EasyWine64.app -rw-r--r-- 1 501 0 299998976 11 24 05:08 EasyWine64.app.zip.001 -rw-r--r-- 1 501 0 14705401 11 24 05:08 EasyWine64.app.zip.002
圧縮レベル 0 で圧縮します。
7z a -mx=0 EasyWine64.app.zip.001.zip EasyWine64.app.zip.001 7z a -mx=0 EasyWine64.app.zip.002.zip EasyWine64.app.zip.002
$ ls total 1271880 drwxr-xr-x 3 501 0 96 11 22 20:21 EasyWine64.app -rw-r--r-- 1 501 0 299998976 11 24 05:08 EasyWine64.app.zip.001 -rw-r--r-- 1 501 0 299999154 11 24 05:11 EasyWine64.app.zip.001.zip -rw-r--r-- 1 501 0 14705401 11 24 05:08 EasyWine64.app.zip.002 -rw-r--r-- 1 501 0 14705579 11 24 05:11 EasyWine64.app.zip.002.zip
これで pixivFANBOX や BOOTH にアップロード出来るようになりました。
解凍は無圧縮 ZIP 分を解凍したら 001
のファイルをそのまま渡せば 7z
コマンドがよしなにやってくれます。
7z x EasyWine64.app.zip.001.zip 7z x EasyWine64.app.zip.002.zip 7z x EasyWine64.app.zip.001
dd コマンドによる分割を試す
bs
、count
、skip
の組み合わせで…(めんどくさい)