圧縮されているとは気付けない圧縮ファイルを観察する

ちょっと昔の話になるが、OSX 10.5(Leopard) から OSX 10.6(Snow Leopard) に移行する時に、アップルはファイルシステムにある仕掛けをした。その仕掛けはとても巧妙で、普通に使っていると、とても気付けるものではない。(自分自身もその仕掛けをある程度理解できたのは、ごく最近のことである。)今回はその仕掛けを追跡してみる。

準備

  • 実験用の外付けハードディスクを用意して、パーティションを3分割した。
  • そこにLeopardSnow Leopard、Mountain Lionをインストールした。
  • 基本的にLeopard環境で起動して、Snow Leopard、Mountain Lionのファイルを観察するのだ。
  • Snow Leopard、Mountain Lion環境で起動しても、進化したOSの仕組みに隠蔽されてしまい、何も見えない。

OSのインストールサイズ

  • LeopardからSnow Lepardに移行すると、嬉しいことに若干ハードディスクの空き容量が増える。
  • 最小限のOSをインストールして比較してみると、Snow Leopardの方が5GB以上空き容量が増加。
      • それぞれのOS環境から計測
空き領域 使用領域 HD容量
Leopard 33.81GB 12.77GB 46.58GB
Snow Leopard 39.13GB 10.88GB 50.01GB

計算基準の変更

  • しかし、空き容量が増えたからといって、単純に喜んではいけない...。
  • Snow Leopard以降、1KB、1MB、1GB等の単位を計算する基準が変わっているのだ。
1KB 1MB 1GB 1TB
Leopard 1,024 1,048,576(1024×1024) 1,073,741,824(1024×1024×1024) 1,099,511,627,776(1024×1024×1024×1024)
Snow Leopard 1,000 1,000,000(1000×1000) 1,000,000,000(1000×1000×1000) 1,000,000,000,000(1000×1000×1000×1000)
  • 1024=2の10乗であり、1000=10の3乗である。
  • Leopardまではアップルは1024を基準とする単位を使ってきた。*1
  • すると、GB単位では7%以上、TB単位では10%近くの差になる。

計算方法を変えるなんてズルいぞアップル!と思ってしまうのだけど、それなりの事情はあった。

  • ほとんどのハードディスクメーカーが10進数のキロバイト単位を基準にしているのに対し、
  • OSXが2進数のキビバイト単位を使っていると、今後さらに感覚的な差異が広がってしまう。
  • それを嫌っての計算基準の変更と思われる。
  • よって、どちらもLeopard環境から見て計測すると、以下のような結果となった。
空き領域 使用領域 HD容量
Leopard 33.81GB 12.77GB 46.58GB
Snow Leopard 36.69GB 9.89GB 46.58GB


それでも3GB近く空き領域が増加している!アップルは、何をしたのか?

PowerPCコードの削減

  • Snow Leopardでは、PowerPC環境をサポートしなくなったので、アップル製のアプリケーションからPowerPCコードが削除されることとなった。
    • 但し、Rosetta環境はインストールできるので、PowerPCコードのアプリケーションを実行することは可能。
  • Leopardまでは、アプリケーションは少なくともPowerPCインテル2つ以上のコードを保持していたので、約半分のコード削減になる。
  • しかし、実行コードはアプリケーションのごく一部なので、約半分になったとしても、それほど大きな節約にはならないかもしれない。
    • 例えばLeopardのMail.appは286.5MBのサイズだが、その中の実行コード Contents/MacOS/Mail のサイズは5.6MBしかない。

実行コード以外のファイル

  • では、大半を占める実行コード以外ファイルの状況はどうなっているだろうか?
  • PNGJPEGAACMPEGなど、ほとんどの画像・音楽・映像ファイルは何らかの圧縮によって保存されている。
  • また、OSXの設定ファイルの要となるプロパティリスト(plist、xml)も、デフォルトでバイナリ化されて保存されるようになった。
  • しかし、これらのことは何もSnow Leopardから始まった訳ではなく、Leopardの頃からほぼ同じ状況であった。
  • 今やほとんどのファイルがすでに圧縮されている。
  • 圧縮されていないのは、テキストファイルと(PowerPCコードが削除された)実行コードくらいなものだろう。


そんな状況でSnow Leopardはいかにして3GBの領域を捻出したのか?

com.apple.ResourceForkで圧縮保存

 $ ls -lh /Volumes/Snow\ Leopard/Applications/Mail.app/Contents/MacOS/Mail
 -rwxr-xr-x@ 1 bebe  staff     0B  7 24  2009 /Volumes/Snow Leopard/Applications/Mail.app/Contents/MacOS/Mail

 $ file /Volumes/Snow\ Leopard/Applications/Mail.app/Contents/MacOS/Mail
 /Volumes/Snow Leopard/Applications/Mail.app/Contents/MacOS/Mail: empty
  • なんと!0B(バイト)である!いくら何でもアップルやり過ぎ。一体どんな圧縮技法を使ってるのか?
  • そもそも0バイトって、ファイルの内容が存在しないという意味である。存在するのはファイル名のみ?
  • 実はその辺に秘密があって、それこそがアップルの仕掛けである。
  • duコマンドで見ると、2.8MBの存在が確認できる。(ホッとした)
 $ du -h /Volumes/Snow\ Leopard/Applications/Mail.app/Contents/MacOS/Mail
 2.8M	/Volumes/Snow Leopard/Applications/Mail.app/Contents/MacOS/Mail
  • では、その存在はどこにあるのか?
 $ ls -lOe@h /Volumes/Snow\ Leopard/Applications/Mail.app/Contents/MacOS/Mail
 -rwxr-xr-x@ 1 bebe  staff  -    0B  7 24  2009 /Volumes/Snow Leopard/Applications/Mail.app/Contents/MacOS/Mail
	com.apple.ResourceFork	 2.8M 
	com.apple.decmpfs	  16B 

 $ xattr -l /Volumes/Snow\ Leopard/Applications/Mail.app/Contents/MacOS/Mail
 com.apple.ResourceFork:
 0000   00 00 01 00 00 2D 05 B1 00 2D 04 B1 00 00 00 32    .....-...-.....2
 ...中略...
 2D05C0   00 00 00 00 00 00 00 00 00 00 1C 00 32 00 00 63    ............2..c
 2D05D0   6D 70 66 00 00 00 0A 00 01 FF FF 00 00 00 00 00    mpf.............
 2D05E0   00 00 00                                           ...

 com.apple.decmpfs:
 0000   66 70 6D 63 04 00 00 00 40 B3 72 00 00 00 00 00    fpmc....@.r.....
  • それは com.apple.ResourceFork と com.apple.decmpfs という拡張属性として保存されていた。
    • 但し、com.apple.ResourceForkが旧来のリソースフォークとして保存されているのか、
    • それとも、拡張属性(EA=Extended Attributes)の一つとして保存されているのか、定かではない...。
  • 一方、com.apple.decmpfsは、このファイルの内容がcom.apple.ResourceForkに圧縮して保存されている、というマーキングである。
  • com.apple.decmpfsの先頭16バイトの内容には、以下の意味がある。
バイトコード 項目 内容 意味
66 70 6D 63 compression magic cmpf 圧縮手法がcmpf
04 00 00 00 compression type 4 (resource fork has compressed data) 圧縮タイプは4(リソースフォークにzlib圧縮データがある)
40 B3 72 00 00 00 00 00 uncompressed size 7516992 bytes 圧縮前のサイズはバイトコードを逆順に並べた16進数 $72 B3 40

素晴らしい!

  • つまりOSXは、com.apple.decmpfsのタイプ4を見つけると、
  • com.apple.ResourceForkにある圧縮データを解凍して、
  • それをファイル内容として読み込んでくれるのだ。
  • 以上の一連の動作は、すべてOSのファイルシステムの中で自動化され完結されている。
  • よってユーザーは、ファイルが圧縮されているかどうかなんて全く意識する必要はない。
  • ファイルの扱いは今までと全く変わらないのだ。


圧縮タイプには、もう2種類ある。

com.apple.decmpfsに圧縮保存

  • 一つは、com.apple.decmpfsにデータを含めてzlib圧縮で保存するタイプ。
  • 上記の圧縮タイプ4では、com.apple.decmpfs=com.apple.ResourceForkに圧縮保存、という単なるマーカーであったが、
  • 圧縮タイプ3では、com.apple.decmpfsの中に圧縮したデータも含んで保存するのだ。
 $ ls -lOe@h /Volumes/Snow\ Leopard/Applications/Mail.app/Contents/version.plist
 -rw-r--r--@ 1 bebe  staff  -    0B  7 24  2009 /Volumes/Snow Leopard/Applications/Mail.app/Contents/version.plist
	com.apple.decmpfs	 263B 

 $ xattr -l /Volumes/Snow\ Leopard/Applications/Mail.app/Contents/version.plist
 com.apple.decmpfs:
 0000   66 70 6D 63 03 00 00 00 BD 01 00 00 00 00 00 00    fpmc............
 0010   78 5E 7D 90 D1 6A 83 30 14 86 AF E7 53 A4 B9 D7    x^}..j.0....S...
 0020   63 61 63 63 A4 96 A9 2D 14 5C 27 68 07 BB 94 24    cacc...-..'h...$
 0030   B4 D9 A2 09 31 CE F5 ED 17 AB 50 26 74 B9 0A 27    ....1.....P&t..'
 0040   DF F7 9F 93 43 D6 3F B5 44 DF DC B4 42 35 2B BC    ....C.?.D...B5+.
 0050   0C 42 8C 78 43 15 13 CD 71 85 0F E5 D6 7F C2 EB    .B.xC...q.......
 0060   C8 23 8B F4 2D 29 3F F2 0D D2 52 B4 16 E5 87 38    .#..-)?...R....8
 0070   DB 25 08 FB 00 2F 5A 4B 0E 90 96 29 CA B3 5D 51    .%.../ZK...)..]Q
 0080   22 97 01 B0 D9 63 84 4F D6 EA 67 80 BE EF 83 6A    "....c.O..g....j
 0090   A0 02 AA EA 01 6C 21 37 4A 73 63 CF 99 0B F3 9D    .....l!7Jsc.....
 00A0   10 30 CB B0 6B 33 A6 FF 19 C7 55 99 A0 36 F2 EE    .0..k3....U..6..
 00B0   C8 17 3F 47 71 27 24 7B 1F 01 02 43 C5 3D B4 D6    ..?Gq'${...C.=..
 00C0   B8 79 A3 25 81 E9 36 C1 C9 36 EE 1A 26 79 71 52    .y.%..6..6..&yqR
 00D0   C6 4E 52 71 21 E6 EA 7D 10 DE 92 6F 35 0B 1F 1F    .NRq!..}...o5...
 00E0   E6 8A FB D6 27 A7 76 5F D5 7C 8E BF 56 42 CE F1    ....'.v_.|..VB..
 00F0   42 75 86 FE 97 1F BA 73 95 08 8C 8B 20 70 59 53    Bu.....s.... pYS
 0100   E4 FD 02 8F 9D 8F 15                               .......
バイトコード 項目 内容 意味
66 70 6D 63 compression magic cmpf 圧縮手法がcmpf
03 00 00 00 compression type 3(xattr has compressed data) 圧縮タイプは3(拡張属性にzlib圧縮データがある)
BD 01 00 00 00 00 00 00 uncompressed size 8 bytes 圧縮前のサイズはバイトコードを逆順に並べた16進数 $01 BD

com.apple.decmpfsにテキスト保存

  • もう一つは、com.apple.decmpfsにデータを含めて非圧縮のテキストで保存するタイプ。
 $ ls -lOe@h /Volumes/Snow\ Leopard/Applications/Mail.app/Contents/PkgInfo
 -rw-r--r--@ 1 bebe  staff  -    0B  7 24  2009 /Volumes/Snow Leopard/Applications/Mail.app/Contents/PkgInfo
	com.apple.decmpfs	  25B 

 $ xattr -l /Volumes/Snow\ Leopard/Applications/Mail.app/Contents/PkgInfo
 com.apple.decmpfs:
 0000   66 70 6D 63 03 00 00 00 08 00 00 00 00 00 00 00    fpmc............
 0010   FF 41 50 50 4C 65 6D 61 6C                         .APPLemal
バイトコード 項目 内容 意味
66 70 6D 63 compression magic cmpf 圧縮手法がcmpf
03 00 00 00 compression type 3 (xattr has inline data) 圧縮タイプは3(拡張属性にインラインデータ=非圧縮のテキストデータがある)
08 00 00 00 00 00 00 00 uncompressed size 8 bytes 圧縮前のサイズはバイトコードを逆順に並べた16進数 $08
      • タイプ3が圧縮データかテキストデータかの判定は、上記16バイトに続く保存データの先頭を見ているようだ。
      • 78 5Eで始まれば圧縮データ。
      • FFで始まればテキストデータ。

テキストデータのままcom.apple.decmpfsへ保存する効果

  • 8バイトの「APPLemal」というデータを、どこに保存しようがバイト数が変わらないんだから意味ないじゃないか?と思うかもしれない。
  • しかし、HFS+がどのようにデータを保管する仕組みになっているかを思い出してみると、その素晴らしい効果に気づくはず。(すごい!)
  • HFS+は、ハードディスクを4KBのセクタという領域に区切って管理する。
  • つまり、アクセスできる最小の単位は4096バイト=4KBごとなのである。
  • よって、たとえ1バイトのファイルを保存しても、ハードディスク上は4096バイトの領域を占領してしまうのだ。

もう少し追求してみる。

  • すごく大ざっぱに言ってしまえば、HFS+にはデータ、リソース、アトリビュートの3つの保存領域がある。
    • データは主役となるファイルの内容である。
    • リソースとアトリビュートは、データに付随する属性情報である。
  • HFS+は、データとリソースについては「目次と、そこからリンクする内容(セクタ)」に分けて管理する。
    • よって、1バイトの内容でも、「目次」からリンクする「内容(セクタ)」として、4096バイトの領域を占領してしまうのである。
  • 一方、アトリビュートについては、「目次と内容」が分かれていない。「目次」の中にそのまま「内容」も含めて保存してしまう方式である。
    • すると、1バイトの「内容」は、「目次」に含まれてしまう!
    • 「目次」のバイト数は1バイト増えるが、「内容(セクタ)」の4096バイトが不要になる。
    • 結果として、その差4095バイトもの節約になるのだ!
  • 圧縮はしていないが、データの格納方法を工夫することで、保存領域を効率よく使っているのだ。
    • 但し、「目次」の中には、それほど大きな情報は保存できない。
    • タイプ4とタイプ3を使い分けて保存している理由はその辺にある。

アプリケーションバンドルの観察

  • つまり、テキストあるいは圧縮して4096バイト以内に収まるファイルなら、com.apple.decmpfsに保存してしまった方が効率的なのである。
  • そのような視点でMail.appの中身を覗いてみると、Contents/Resources/ 内の小さなファイルは、ほとんどが0バイトと表示されている。
 $ ls -lh /Volumes/Snow\ Leopard/Applications/Mail.app/Contents/Resources/*.tiff
 -rw-r--r--@ 1 bebe  staff     0B  7 24  2009 /Volumes/Snow Leopard/Applications/Mail.app/Contents/Resources/AccountPreferences.tiff
 -rw-r--r--@ 1 bebe  staff     0B  7 24  2009 /Volumes/Snow Leopard/Applications/Mail.app/Contents/Resources/Action.tiff
 -rw-r--r--@ 1 bebe  staff     0B  7 24  2009 /Volumes/Snow Leopard/Applications/Mail.app/Contents/Resources/Action_Pressed.tiff
 -rw-r--r--@ 1 bebe  staff     0B  7 24  2009 /Volumes/Snow Leopard/Applications/Mail.app/Contents/Resources/Add.tiff
 ...中略...

 $ ls -lOe@h /Volumes/Snow\ Leopard/Applications/Mail.app/Contents/Resources/AccountPreferences.tiff
 -rw-r--r--@ 1 bebe  staff  -    0B  7 24  2009 /Volumes/Snow Leopard/Applications/Mail.app/Contents/Resources/AccountPreferences.tiff
	com.apple.decmpfs	 2.0K 
  • 実はアプリケーションというファイルの集合体の中には、このような4KBに満たない小さなファイルがたくさんある。
  • それらの小さなファイルを、一つの「目次」ファイルとしてまとめてしまえるのだ。その効果は意外と大きいだろう。
  • また、4096バイトを超える場合は、com.apple.ResourceForkに圧縮データを保存している。
  • 最低4KB以上のzlib圧縮されたファイルなのだから、当然、それなりの効果が期待できるのだ。
    • 圧縮前の元データは、倍の8KBくらいあってもおかしくないはず。
 $ ls -lOe@h /Volumes/Snow\ Leopard/Applications/Mail.app/Contents/Resources/Mail.rsrc
 -rw-r--r--@ 1 bebe  staff  -    0B  7 24  2009 /Volumes/Snow Leopard/Applications/Mail.app/Contents/Resources/Mail.rsrc
	com.apple.ResourceFork	 9.6K 
	com.apple.decmpfs	  16B 
  • さらに、アプリケーションだけに留まらず、コマンドファイルについても同様に圧縮されている。
 $ ls -lOe@h /Volumes/Snow\ Leopard/bin/ls
 -r-xr-xr-x@ 1 bebe  staff  -    0B  7 14  2009 /Volumes/Snow Leopard/bin/ls
	com.apple.ResourceFork	  30K 
	com.apple.decmpfs	  16B 
 $ ls -lOe@h /bin/ls
 -r-xr-xr-x  1 root  wheel  -   72K 10  6  2007 /bin/ls
  • なんと、72KB - 30KB = 40KBも節約されているのだ。(圧縮率50%以上)


このようにしてSnow Leopard以降、ほとんどすべての実行ファイルがHFS+内部の仕組みによって、圧縮保存されるようになったのである。

隠蔽される現象

  • 以上の観察記録は、すべてLeopard環境から観察しないと、進化したOSの仕組みに隠蔽されてしまって、何も見えない。
  • 例えば、今ブログを書いているMountain Lionからlsコマンドを確認してみると...
 $ ls -lOe@h /bin/ls
 -rwxr-xr-x  1 root  wheel  compressed   34K  9 24  2012 /bin/ls

 $ xattr -l /bin/ls
  • わずかにcompressed(圧縮された)というファイルフラグは確認できるものの、拡張属性は何も表示されない。
  • 一方、Leopard環境からlsコマンドを確認してみると...
 $ ls -lOe@h /Volumes/Mountain\ Lion/bin/ls 
 -rwxr-xr-x@ 1 bebe  staff  -    0B  4 23 09:43 /Volumes/Mountain Lion/bin/ls
	com.apple.ResourceFork	  15K 
	com.apple.decmpfs	  16B 

 $ xattr -l /Volumes/Mountain\ Lion/bin/ls
 com.apple.ResourceFork:
 0000   00 00 01 00 00 00 3C 88 00 00 3B 88 00 00 00 32    ......<...;....2
 0010   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 0020   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 0030   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 0040   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 0050   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 0060   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 0070   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 0080   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 0090   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 00A0   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 00B0   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 00C0   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 00D0   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 00E0   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 00F0   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
 0100   00 00 3B 84 01 00 00 00 0C 00 00 00 78 3B 00 00    ..;.........x;..
 0110   78 5E ED 7D 09 5C 13 47 F4 F0 26 10 2E 81 00 A2    x^.}...G..&.....
...中略...

 com.apple.decmpfs:
 0000   66 70 6D 63 04 00 00 00 A0 87 00 00 00 00 00 00    fpmc............
  • ちゃんと、com.apple.ResourceFork と com.apple.decmpfs が見えるのだ。
  • 進化したOS環境では、com.apple.ResourceFork と com.apple.decmpfs は隠蔽されてしまうようだ。
  • ちなみに、ファイルサイズも本来は15KB程度なのに、解凍後のサイズ34KBと表示されている。

afsctool

  • 隠蔽されてしまうと、面白くない...。
  • そんな時はafsctoolを使ってみる。
  • Homebrewで素早くインストールできる。
$ brew install afsctool
観察
  • lsコマンドを観察してみたところ。
$ afsctool -v /bin/ls
/bin/ls:
File is HFS+ compressed.
File content type: public.unix-executable
File size (uncompressed data fork; reported size by Mac OS 10.6+ Finder): 34720 bytes / 35 KB (kilobytes) / 34 KiB (kibibytes)
File size (compressed data fork - decmpfs xattr; reported size by Mac OS 10.0-10.5 Finder): 15546 bytes / 16 KB (kilobytes) / 16 KiB (kibibytes)
File size (compressed data fork): 15562 bytes / 16 KB (kilobytes) / 16 KiB (kibibytes)
Compression savings: 55.2%
Number of extended attributes: 0
Total size of extended attribute data: 0 bytes
Approximate overhead of extended attributes: 536 bytes
Approximate total file size (compressed data fork + EA + EA overhead + file overhead): 17184 bytes / 17 KB (kilobytes) / 17 KiB (kibibytes)
  • Mail.appを観察してみたところ。
$ afsctool -v /Applications/Mail.app
/Applications/Mail.app:
Number of HFS+ compressed files: 3601
Total number of files: 3804
Total number of folders: 75
Total number of items (number of files + number of folders): 3879
Folder size (uncompressed; reported size by Mac OS 10.6+ Finder): 54932927 bytes / 63.1 MB (megabytes) / 60.2 MiB (mebibytes)
Folder size (compressed - decmpfs xattr; reported size by Mac OS 10.0-10.5 Finder): 27584627 bytes / 32.6 MB (megabytes) / 31.1 MiB (mebibytes)
Folder size (compressed): 31465071 bytes / 36.5 MB (megabytes) / 34.8 MiB (mebibytes)
Compression savings: 42.7%
Approximate total folder size (files + file overhead + folder overhead): 38918672 bytes / 38.9 MB (megabytes) / 37.1 MiB (mebibytes)
  • どれだけ圧縮されているかがよく分かる。
HFS+圧縮
      • HFS+圧縮を試す前に、バックアップを忘れずに!
      • afsctoolコマンドはOSXデフォルトではないのだ。
  • さらに、任意のファイルに対して、HFS+圧縮することもできる。
  • まずは非圧縮のhello.txtを作ってみた。
$ echo hello world > hello.txt

$ afsctool -v hello.txt
/Users/bebe/hello.txt:
File is not HFS+ compressed.
File data fork size (reported size by Mac OS X Finder): 12 bytes / 4 KB (kilobytes) / 4 KiB (kibibytes)
Number of extended attributes: 0
Total size of extended attribute data: 0 bytes
Approximate overhead of extended attributes: 0 bytes
Approximate total file size (data fork + resource fork + EA + EA overhead + file overhead): 4344 bytes / 4 KB (kilobytes) / 4 KiB (kibibytes)
  • afsctool -cオプションで、指定したファイルをHFS+圧縮できる。
$ afsctool -c hello.txt

$ afsctool -v hello.txt
/Users/bebe/hello.txt:
File is HFS+ compressed.
File size (uncompressed data fork; reported size by Mac OS 10.6+ Finder): 12 bytes / 0 KB (kilobytes) / 0 KiB (kibibytes)
File size (compressed data fork - decmpfs xattr; reported size by Mac OS 10.0-10.5 Finder): 0 bytes / 0 KB (kilobytes) / 0 KiB (kibibytes)
File size (compressed data fork): 29 bytes / 0 KB (kilobytes) / 0 KiB (kibibytes)
Compression savings: -141.7%
Number of extended attributes: 0
Total size of extended attribute data: 0 bytes
Approximate overhead of extended attributes: 268 bytes
Approximate total file size (compressed data fork + EA + EA overhead + file overhead): 545 bytes / 1 KB (kilobytes) / 1 KiB (kibibytes)
  • 余裕で4KB以内なので、com.apple.decmpfsの中に転送されたはず。
  • ちなみに、Leopard環境から観察すると、このように見える。
      • 圧縮前
 $ ls -lOe@h /Volumes/Snow\ Leopard/Users/bebe/hello.txt
 -rw-r--r--  1 bebe  staff  -   12B  8  1 11:47 /Volumes/Snow Leopard/Users/bebe/hello.txt
      • 圧縮後
 $ ls -lOe@h /Volumes/Snow\ Leopard/Users/bebe/hello.txt
 -rw-r--r--@ 1 bebe  staff  -    0B  8  1 11:43 /Volumes/Snow Leopard/Users/bebe/hello.txt
	com.apple.decmpfs	  29B 

 $ xattr -l /Volumes/Snow\ Leopard/Users/bebe/hello.txt
 com.apple.decmpfs:
 0000   66 70 6D 63 03 00 00 00 0C 00 00 00 00 00 00 00    fpmc............
 0010   FF 68 65 6C 6C 6F 20 77 6F 72 6C 64 0A             .hello world.
  • OSX標準のdittoコマンドでもHFS+の圧縮は利用できるが、元ファイル(またはフォルダ)を上書き保存できないところがちょっと不便。
$ ditto --hfsCompression hello.txt hello-compressed.txt
  • afsctoolコマンドなら、元ファイル(またはフォルダ)を上書きして、素早く圧縮を完了してくれる。
    • ちなみに、root wheel権限のアプリケーションなどは、sudo afsctool -c file_or_folder のようにroot権限で実行する必要がある。

HFS+圧縮が解除されるとき

  • OSインストール時には、ほとんどすべてのアプリケーションやコマンドのファイルは、HFS+圧縮を利用した状態でコンパクトに保存されている。
  • ところが、ソフトウェアアップデート等でアプリケーションが更新された時、HFS+圧縮は解除され、通常のデータフォークを利用した保存状態に戻ってしまう。
  • アプリケーションはフォルダ構造なので、そのフォルダ中の更新されたファイルだけが、HFS+圧縮を解除される。
  • この現象は、デフォルトのOSのファイル保存機能としては、HFS+圧縮を利用していないことを意味すると思う。
  • HFS+圧縮で保存するためには、dittoコマンドやafsctoolコマンド等を利用して、別途圧縮する必要があるのだ。
  • 例えば、iTunesは頻繁にアップデートされるので、アップデート後はHFS+圧縮を利用しない状態で保存されているはず。
    • 一部のファイルだけはHFS+圧縮されているかもしれないが、ほとんどのファイルは通常の非圧縮な状態かもしれない。
    • (圧縮による減少比率:8.5%、圧縮による減少容量:335.7 - 310.7 = 25MB)
$ afsctool -v /Applications/iTunes.app
/Applications/iTunes.app:
Number of HFS+ compressed files: 651
Total number of files: 9151
Total number of folders: 4205
Total number of items (number of files + number of folders): 13356
Folder size (uncompressed; reported size by Mac OS 10.6+ Finder): 314312694 bytes / 335.7 MB (megabytes) / 320.1 MiB (mebibytes)
Folder size (compressed - decmpfs xattr; reported size by Mac OS 10.0-10.5 Finder): 286899615 bytes / 307 MB (megabytes) / 292.8 MiB (mebibytes)
Folder size (compressed): 287707834 bytes / 307.8 MB (megabytes) / 293.6 MiB (mebibytes)
Compression savings: 8.5%
Approximate total folder size (files + file overhead + folder overhead): 310688555 bytes / 310.7 MB (megabytes) / 296.3 MiB (mebibytes)
  • そんな時は、afsctoolの出番である!
$ sudo afsctool -c /Applications/iTunes.app
Password:
/Applications/iTunes.app:
Number of HFS+ compressed files: 8148
  • これでHFS+圧縮された状態になった。
    • (圧縮による減少比率:39.9%、圧縮による減少容量:335.7 - 200.9 = 134.8MB)
$ afsctool -v /Applications/iTunes.app
/Applications/iTunes.app:
Number of HFS+ compressed files: 8148
Total number of files: 9151
Total number of folders: 4205
Total number of items (number of files + number of folders): 13356
Folder size (uncompressed; reported size by Mac OS 10.6+ Finder): 314312694 bytes / 335.7 MB (megabytes) / 320.1 MiB (mebibytes)
Folder size (compressed - decmpfs xattr; reported size by Mac OS 10.0-10.5 Finder): 181741506 bytes / 188.4 MB (megabytes) / 179.7 MiB (mebibytes)
Folder size (compressed): 188890491 bytes / 195.6 MB (megabytes) / 186.5 MiB (mebibytes)
Compression savings: 39.9%
Approximate total folder size (files + file overhead + folder overhead): 200946009 bytes / 200.9 MB (megabytes) / 191.6 MiB (mebibytes)
  • iTunes.appではこの程度だが、Snow LeopardのDevelopperフォルダや、Mountain LionのXcode.appなら、さらに効果は大きい。
    • (圧縮による減少比率:57.9%、圧縮による減少容量:1.84 - 0.7959 = 1.0441GB)
$ sudo afsctool -c /Developer
Password:
/Developer:
Number of HFS+ compressed files: 45065

$ afsctool -v /Developer
/Developer:
Number of HFS+ compressed files: 44998
Total number of files: 49904
Total number of folders: 10268
Total number of items (number of files + number of folders): 60172
Folder size (uncompressed; reported size by Mac OS 10.6+ Finder): 1718534353 bytes / 1.84 GB (gigabytes) / 1.72 GiB (gibibytes)
Folder size (compressed - decmpfs xattr; reported size by Mac OS 10.0-10.5 Finder): 681614752 bytes / 724.5 MB (megabytes) / 690.9 MiB (mebibytes)
Folder size (compressed): 723967491 bytes / 766.9 MB (megabytes) / 731.3 MiB (mebibytes)
Compression savings: 57.9%
Approximate total folder size (files + file overhead + folder overhead): 795889330 bytes / 795.9 MB (megabytes) / 759 MiB (mebibytes)
    • (圧縮による減少比率:50.2%、圧縮による減少容量:3.8 - 1.86 = 1.94GB)
$ afsctool -v /Applications/Xcode.app
/Applications/Xcode.app:
Number of HFS+ compressed files: 94340
Total number of files: 99914
Total number of folders: 18741
Total number of items (number of files + number of folders): 118655
Folder size (uncompressed; reported size by Mac OS 10.6+ Finder): 3541020150 bytes / 3.8 GB (gigabytes) / 3.54 GiB (gibibytes)
Folder size (compressed - decmpfs xattr; reported size by Mac OS 10.0-10.5 Finder): 1687689704 bytes / 1.73 GB (gigabytes) / 1.61 GiB (gibibytes)
Folder size (compressed): 1761888802 bytes / 1.81 GB (gigabytes) / 1.68 GiB (gibibytes)
Compression savings: 50.2%
Approximate total folder size (files + file overhead + folder overhead): 1862841950 bytes / 1.86 GB (gigabytes) / 1.73 GiB (gibibytes)


GB単位の圧縮も可能になるのだ!
HFS+圧縮は、素晴らしい技術だ!

*1:ちなみに、Mac OSの頃からずっと1024を基準としていた、と記憶している。