MacのZIPをWindowsで解凍すると化ける理由と、送る前の直し方

送った書庫を相手が開いたら、ファイル名が読めない記号の列になっていた。中身のフォルダの横に __MACOSX という見覚えのないフォルダが並び、書類には ._ で始まる同名のファイルが付いている。mac で zip 圧縮 windows で解凍という検索は、たいていこの状態の報告を受けた直後に始まります。結論を先に書くと、これは転送の失敗ではなく、Macが書いたとおりの書庫をWindowsが仕様どおりに読んだ結果です。そして症状は4つに分かれていて、原因も直し方も別々です。

MacとWindowsが混ざる職場で、この問題が消えない理由

同じ社内でも、制作や開発はMac、経理や営業事務はWindows、という分かれ方は珍しくありません。取引先まで含めれば、送った書庫がどちらの環境で開かれるかを送信者が知らないほうが普通です。ZIPという形式そのものは両方で開けるため、形式を選ぶ段階では問題が見えません。

やり取りの経路が増えたことも効いています。メールの添付だけだった時代と違い、いまはチャットのファイル共有、クラウドストレージの共有リンク、案件ごとのポータルと入口が分かれ、それぞれ扱えるサイズや扱えるファイル名の規則が違います。書庫にまとめて1個にすれば経路の違いを吸収できる、という発想でZIPが選ばれ続けている一方で、書庫の中身が環境をまたぐときの決まりごとは、送る側の手元では確認されないまま流れていきます。

さらに、圧縮はほとんどの人にとって右クリック1回の作業です。作業として軽いぶん、何が入ったかを確かめる工程が最初から組み込まれていません。結果として、相手から報告が来て初めて中身を知る、という順番が固定されます。この順番を変えるだけでも、送り直しの回数はかなり減ります。

送った書庫がWindows側で崩れる4つの症状

同じ「文字化けした」という報告でも、実際に起きていることは次のどれかです。混ぜたまま対処すると、送り直しを何度も繰り返すことになります。

  • 名前が読めない記号になる。これは文字コードの問題で、書庫の中の1ビットで決まります
  • __MACOSX というフォルダと ._ で始まるファイルが並ぶ。これはAppleDoubleという形式で、ZIPに置き場所のない情報を退避したものです
  • どのフォルダにも .DS_Store という隠しファイルが混ざる。Finderがフォルダごとの表示状態を書き込んだファイルです
  • 展開が途中で止まる。Windowsで使えない文字が名前に入っているか、パスが長すぎるかのどちらかです

このうち相手側の設定で救えるのは1つ目だけで、それも相手が使う解凍ソフトによります。残りの3つは送る側で作り直すしかありません。

名前が化けるかどうかは、書庫の中の1ビットで決まる

ZIPは、ファイル名を「生のバイト列」と「そのバイト列をどう読むかを示すフラグ」の組で保存します。仕様書はこのフラグをはっきり定義しています。

Bit 11: Language encoding flag (EFS). If this bit is set, the filename and comment fields for this file MUST be encoded using UTF-8. 出典: pkware.cachefly.net

このビットが立っていれば、名前はUTF-8として読まれます。立っていないと、解凍する側は昔からの動作にならい、その環境の既定の文字コードで読もうとします。日本語版Windowsの既定はShift_JIS系のコードページなので、UTF-8のバイト列をそこへ通すと意味のある文字にはなりません。バイト列そのものは壊れておらず、読み方の指定だけが抜けている状態です。

問題は、macOSに最初から入っている道具ではこのビットを立てられない点にあります。ターミナルで zip -v を実行すると、Info-ZIP Zip 3.0のビルド情報が表示されますが、「Zip special compilation options」の行の中身は空です。Unicodeの扱いはこのコンパイル時オプションで有効になる機能なので、ヘルプに載っている文字コード関連のスイッチは実際には効きません。-UN=UTF8 を付けて実行しても、そんなオプションは無いという引数エラーで止まります。

同じことは書庫の中身を調べても確認できます。ターミナルの zip で作った書庫と、ditto -c -k で作った書庫の両方を開くと、日本語のファイル名はUTF-8のバイト列として入っている一方で、EFSのビットは立っていません。つまり、標準の道具だけを使う限り、名前を「これはUTF-8です」と宣言した書庫は作れません。

__MACOSX._ が並ぶ理由

このフォルダは不具合でも消し忘れでもなく、macOSが書庫を作るときに使う仕組みそのものです。書庫作成に使われる ditto コマンドの説明書には、--sequesterRsrc というオプションについて、PKZip形式の書庫を作るときにリソースフォークとHFSのメタデータを __MACOSX というサブディレクトリに保存する、と書かれています。

ZIPにはリソースフォークや拡張属性を入れる場所がありません。そこで、本体とは別にAppleDouble形式のファイルを作り、影のフォルダにまとめて入れます。別のMacで展開すると、この対応関係を理解して元の情報を戻したうえで隠すので、送る側は最後まで気づきません。Windowsから見ると、これは単なるファイルの山です。

同じ現象は書庫の外でも起きます。拡張属性を保存できない形式のUSBメモリにコピーすると、._ で始まるファイルが本体の隣に残ります。FAT形式は容量32GBが1つの目安で、ボリューム名は11文字までという制約もあり、Windowsとの受け渡し用に用意した外付けほどこの状態になりやすくなります。

macOSにはこの掃除のための dot_clean というコマンドが最初から入っています。使い方の行には -m が「常にAppleDoubleファイルを削除する」として並んでいます。圧縮する前にフォルダへ当てておけば、書庫に巻き込まれる分を先に減らせます。

送る前に書庫を作り直す手順

Finderの「圧縮」以外にも作り方があり、出来上がる中身が違います。

作り方 __MACOSX .DS_Store 名前のUTF-8フラグ
Finderの「圧縮」 入る 入る 立たない
zip -r 書庫.zip フォルダ 入らない 除外しなければ入る 立たない
ditto -c -k --sequesterRsrc 入る 入る 立たない
ditto -c -k --norsrc --noextattr 入らない 入る 立たない
別途入れた圧縮ソフト 道具による 道具による 立つものが多い

注目したいのは2行目です。ターミナルの zip はAppleDoubleを作らないので、社外へ出す書庫の出発点としてはFinderの「圧縮」より扱いやすくなります。一方で、最初から入っている道具だけを使う限り、どの行もフラグは立ちません。だから次に書く命名の話が効いてきます。

実際の手順は次のとおりです。掃除してから、除外を指定して圧縮します。

dot_clean -m ~/Desktop/handover
cd ~/Desktop
zip -r -X handover.zip handover -x "*.DS_Store" -x "__MACOSX/*"

-X は、作成元の環境でしか意味を持たない付加情報を落とすスイッチです。-x の除外指定は圧縮対象のパスより後ろに置きます。前に置くと、対象が選べないという意味のエラーで止まります。

Windowsで通らない名前と、長さの上限

macOSとWindowsでは、ファイル名に使ってよい文字が違います。この差は解凍の瞬間まで表に出ません。

Windowsは \ / : * ? " < > | を名前に使えません。中でもコロンは事故になりやすい文字です。Finderは名前にコロンを打たせませんが、ターミナルやスクリプトからは何の警告もなく作れてしまいます。加えて CON PRN AUX NUL といった古いデバイス名は、拡張子が付いていても名前として使えず、末尾のピリオドと空白は捨てられます。

長さの制限は、両者で数える単位が違います。macOSのファイル名は1つの要素につき255バイトまでで、文字数ではなくバイト数です。日本語は1文字あたり3バイト前後を使うため、英数字の名前より3分の1ほど早く上限に届きます。Windows側はパス全体で数え、多くの解凍ソフトが260文字を超えるパスを書き出しません。手元では問題なく開けるフォルダが、相手のユーザープロファイルの奥で展開された途端に失敗するのはこのためです。

大文字と小文字の扱いも、静かに効いてくる差です。macOSのボリュームは通常、大文字と小文字を区別せずに保存だけは元のまま残す設定なので、同じフォルダに Report.pdfreport.pdf を置くことができず、衝突に気づく機会がありません。区別する設定のボリュームで作った書庫や、複数の場所からスクリプトで集めた書庫には、この2つが同時に入り得ます。Windowsで展開すると片方が黙って上書きされ、受け取った側のファイル数だけが一覧と合わなくなります。

実務上の落としどころは単純です。社外へ出す書庫の中身は、英数字とハイフンとアンダースコアだけの名前に整え、階層を浅くしてから固めます。この1つの決めごとで、文字コードの問題と使えない文字の問題が同時に消えます。日付を頭に付けて 20260904_見積_A社 のような形にしたい場合も、日本語の部分だけをローマ字に置き換えれば規則は保てます。

相手が何で開くかによって結果が変わる

同じ書庫でも、開く道具によって見え方が変わります。片方の担当者からは化けたと言われ、もう片方からは何も言われない、という状況はここから生まれます。

Windowsの標準機能による展開には、選べる設定がありません。書庫を読み、フラグの無い名前を自前の規則で解釈し、そのまま書き出します。文字コードを選ぶ場所も、AppleDoubleを飛ばす指定もありません。別途インストールする圧縮ソフトには、展開時に文字コードを選べるものや、長いパスを扱えるものがあります。

ただし、相手に何を入れてもらうかを前提にした設計は、社内の決まった相手にしか通りません。顧客に渡す資料や、配布用のダウンロードでは、いちばん機能の少ない解凍手段で開けることを前提に作るのが確実です。標準の機能で開けるように作っておけば、高機能な道具ならなおさら問題なく開きます。

圧縮の前に1行確認できるかどうかが分かれ目になる

書庫が期待どおりかは、推測しなくても確かめられます。unzip -l 書庫.zip で中身の一覧が出るので、__MACOSX._.DS_Store が並んでいれば、相手の画面にも同じものが並びます。一覧に出る日本語がターミナルで化けて見えるなら、それは相手が踏むのと同じ状態が別の道具で再現されているだけです。エントリの数が想定より多い書庫は、ファイルごとにAppleDoubleの片割れを抱えています。

問題は、この確認そのものが面倒な点にあります。フォルダの表示から離れ、ターミナルを探し、パスを打ち直す。1回あたり数十秒でも、社外への送付が週に何度もあれば省かれるようになります。フォルダとターミナルとAIが同じ窓にある作りは、この確認を別の場所へ行かずに済ませるためのものです。どこまでを1つの窓で扱えるかはできることにまとめてあります。二画面型のファイル管理や転送用のクライアントとの違いは他のファイル管理との比較で整理していて、費用の考え方は料金に載せています。

確認を仕組みにするなら、手順を覚えるのではなく、掃除と圧縮と一覧表示の3つを1本のスクリプトにまとめて、送付のたびにそれを呼ぶ形にしておくと、担当者が変わっても同じ結果になります。

よくある質問

相手のWindows側の設定で文字化けを直せますか?

展開に使うソフト次第です。文字コードを選べる圧縮ソフトなら、UTF-8として読み直せば元の名前に戻せます。Windowsの標準機能による展開には選ぶ場所がないため、その場合は送る側で名前を英数字に変えて作り直すか、フラグを立てられる圧縮ソフトで固め直すことになります。

`__MACOSX` フォルダは削除してしまって問題ありませんか?

Windows上では中身が使われないので、フォルダごと消しても読める情報は失われません。ただしMacで展開する予定の書庫から消すと、タグやカスタムアイコンなどの付加情報が戻らなくなります。相手の環境で判断を分けてください。

Finderの「圧縮」とターミナルの `zip` では何が変わりますか?

AppleDoubleの扱いが変わります。Finder経由ではリソースフォークが __MACOSX に退避されますが、ターミナルの zip はそれを作りません。一方で、名前にUTF-8のフラグを立てない点はどちらも同じなので、日本語名の化けはどちらでも起こります。

日本語のファイル名は何文字までにしておくと安全ですか?

macOSの上限は255バイトで、日本語は1文字が3バイト前後を占めます。名前だけを見れば80文字程度が目安ですが、Windows側はパス全体で260文字の壁があるため、階層の深さも合わせて短くしておくほうが安全です。

記事一覧へ戻る