0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MacでZipを解凍したら出てくる __MACOSX ディレクトリとPythonでの対処法

Posted at

はじめに

Pythonで画像処理やZipを扱っているときに、なぜか __MACOSX という謎のフォルダや ._xxx という余計なファイルが出てきてエラーになった経験はありませんか?

僕も初めて機械学習用のデータセットを扱ったときに、Pillow(PIL)で画像を開こうとしたら

OSError: cannot identify image file

と怒られて「え?ファイル壊れてる?」とめちゃくちゃ時間を溶かしたことがあります。
原因は macOSが勝手に作る __MACOSX フォルダ でした。

この記事では、Pythonで実務中にハマったこの問題を整理して、実際の対処法をまとめます。

__MACOSX フォルダって何?

macOS の Finder でZip圧縮すると、自動で作られるメタデータ用フォルダ。

アイコンの位置やFinderの表示情報など「macOS独自の情報」を保存しています。

普段は見えないが、WindowsやLinuxで解凍すると __MACOSX ディレクトリ と ._image.jpg のようなファイル として出てきます。

例:

dataset.zip/
├── __MACOSX/
│   └── ._image1.jpg
├── image1.jpg
├── image2.jpg

Python から見ると「中身はゴミ」なので、処理に邪魔になるだけです。

Pythonで起こるトラブル

画像処理のエラー

from PIL import Image
import os

for fname in os.listdir("dataset"):
    img = Image.open(os.path.join("dataset", fname))

このとき ._image1.jpg を読もうとしてエラー。

OSError: cannot identify image file

ファイル数が合わない

本当は100枚あるはずなのに、os.listdir すると ._xxx が混ざって101枚になってしまう。
機械学習で「train: 80, test: 20」に分けたいのにズレる…地味にイライラします。

Pythonでの対処法

1. フィルタして無視する

シンプルに「_MACOSX と . で始まるものを無視」します。

import os

files = [
    f for f in os.listdir("dataset")
    if not f.startswith("._") and f != "__MACOSX"
]

これだけで大体のトラブルは回避可能。

2. 再帰的に探索する場合

os.walk で下層まで探索するならこう書きます。

for root, dirs, files in os.walk("dataset"):
    if "__MACOSX" in root:
        continue
    for f in files:
        if f.startswith("._"):
            continue
        path = os.path.join(root, f)
        print(path)

3. Zip解凍時にスキップ

最初から展開しないのが一番クリーンです。

import zipfile

with zipfile.ZipFile("dataset.zip") as zf:
    for name in zf.namelist():
        if "__MACOSX" in name or name.startswith("._"):
            continue
        zf.extract(name, "dataset")

4. そもそも入れない方法(macOS側)

Zipを作るときに -X オプションを付ければ、余計な情報を含めません。

zip -r -X dataset.zip dataset/

これで __MACOSX なしのクリーンなZipが作れます。
社内で配布するときや、Kaggle用のデータを作るときにめちゃ便利。

まとめ

__MACOSX は macOSがZipに勝手に入れるメタデータ用フォルダのこと。
Pythonで扱うときはエラーやファイル数不一致の原因になることがあります。

対処法は

  • startswith("._") や __MACOSX を無視する
  • os.walk でスキップする
  • zipfile で展開時に除外する
  • 根本的には zip -X で作成 すると最初から入らない

最後に

この __MACOSX 問題、初めて遭遇すると「Pythonが悪いのか?データが壊れてるのか?」と混乱しがちですが、実際には macOSの仕組み由来の「おまけファイル」 です。
Python側では 「無視する」 ことが正解。

実務でデータ処理や機械学習をしている人は、一度は遭遇するので「見かけたら捨てる」習慣を持つと楽になります。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?