Replace DMG with Sparse Bundle Image

前面的文章中介绍了使用大小写不敏感的磁盘镜像为 Steam 开辟一个存储区。但是这有一个弊端,即一旦 DMG 文件建立好,其占用的硬盘空间就固定了,即使没有占满 DMG 内部的空间。为此,我们可以用 macOS 提供的一种动态增长的 Image 结构来替换前文的 DMG 文件,即 Sparse Bundle 格式,这也是 Time Machine 内部使用的格式。该格式可动态增长,增长上限是建立文件时指定的值(可以 resize)。该格式虽然不利于分发,但却是持久化存储的一个非常好的选择。

Convert Existed DMG to Sparse Bundle

我们可以使用 hdiutil 来将一个已有的 DMG 文件转换成新格式。假设已经存在的文件是 Steam.dmg

1
hdiutil convert Steam.dmg -format UDSB -o Steam.sparsebundle

接下来可以选择扩大新镜像的增长上限,比如改成最大占用 100G:

1
hdiutil resize -size 100g Steam.sparsebundle

这并不会导致磁盘空间立刻消失 100G,而是实际使用多少就占用多少空间。

接下来需要更改相应的挂载脚本等信息,在前文的场景中即修改文件~/Library/LaunchAgents/data.steam.dmg.plist 如下,将内容中的 DMG 文件替换为新的文件即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>data.steam.dmg</string>
<key>Program</key>
<string>/usr/bin/hdiutil</string>
<key>ProgramArguments</key>
<array>
<string>hdiutil</string>
<string>attach</string>
<string>-nobrowse</string>
<string>/usr/local/var/Steam.sparsebundle</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>

Create Sparse Bundle from Scratch

新建很简单,可以直接从 Disk Utility 中新建,注意在 Image Format 处选择 sparse bundle disk image 即可。

此外也可以使用 hdiutil 来建立:

1
hdiutil create -type SPARSEBUNDLE -size 100g -fs "APFS" NewImage.sparsebundle

其中 -fs 的参数有很多选择,如 “Case-sensitive APFS”,”Journaled HFS+” 等,完整的列表可以执行 hdiutil create -help 获取。