.DS_Store 这玩意苹果用了 25 年都不删,是故意的

前两天我把一个项目打成 zip 发给合作方,他用 Windows。

过一会儿他截图过来,压缩包解开之后多出一堆叫 .DS_Store 的隐藏文件,双击打开全是乱码。

我说你删了也白搭。只要我这边下次再打开一次那个文件夹,它立刻又会生成一个塞回去。

他追问了一句,这东西到底是干嘛的。

我发现自己居然答不上来。

这就挺尴尬的。

我用 Mac 这么多年,天天见这个文件名。.gitignore 里补这一行不知道补过多少次,把代码发到 Linux 服务器上被同事问这是啥,git push 的时候还因为忘了 ignore,被 reviewer 在 PR 里挂过问号。但我从来没认真想过它到底是干嘛的。

如果不是今天这个用 Windows 的同事一问,我大概永远都想不起来去查它。

先说名字。

DS 原来是 Desktop Services 的缩写。这是 Mac 系统里的一个系统组件。Finder 靠它来管每个文件夹的显示状态,.DS_Store 就是 Desktop Services 给自己往磁盘上落的一个小数据库。

它的全名叫 Desktop Services Store。可能很多用 Mac 的老用户,今天第一次知道它的完整名字是什么。

然后是它的年龄。

它 2001 年 3 月跟着 Mac OS X 10.0 Cheetah 一起发布。到今年 4 月刚好 25 年。

再往下是它里面装的东西,这确实是我完全没想到的。

你在 Finder 里看到的这个文件夹的一切,它都记着。

这个文件夹上次用的是图标、列表、分栏还是画廊视图。

Finder 窗口上次关闭时多大,摆在屏幕哪个位置,滚动条滑到哪一行。

图标视图下你手动把某个图标拖到哪个坐标,吸附到网格的第几行第几列。

这个文件夹的背景你设成了什么颜色,或者用了哪张自定义图片。

甚至按修改时间倒序这种小设置,它都存着。

所以它不是什么垃圾文件,它是每个文件夹的记忆。没有它,Finder 就是一个没有记忆的工具,每次打开都得从头摆一遍。

到这儿故事还没完。

我再往下查还发现一件有意思的事儿。

苹果自家的文件系统 HFS+ 和后来的 APFS,其实都原生支持一套叫扩展属性(xattr)的东西。通俗讲,就是你可以把「窗口上次多大」「图标摆在哪」这种信息,直接写在文件夹自己的元数据里,完全不用单独再开一个肉眼可见的文件。

那苹果为啥不走这条路?偏偏要造一个 .DS_Store 往每个目录里塞?

因为 Mac 以外的世界,没人认 xattr。你的文件本身是完整的,但那些附加信息一旦离开苹果的地盘,就被剥干净了。

你把 Mac 项目压成 zip 扔到 Windows 解压,xattr 没了。

你把文件拷到 FAT32 的 U 盘,xattr 没了。

你用 scp 把代码同步到 Linux 服务器再拉回来,xattr 没了。

你把文件上传到各种网盘再下载回来,xattr 没了。

甚至你用 rsync 在两台 Mac 之间同步,默认参数都不带 xattr。

xattr 这套东西苹果自己在 Mac 里用得很丝滑。但它是苹果自家的规矩。一出家门,没人给它面子。

换个角度想一下。如果 2001 年那个苹果工程师选了 xattr 这条干净的路,会发生什么?

你在 Mac 里精心摆好了一个文件夹,压成 zip 发给同事,让同事原样传回来。你解开一看,窗口大小没了,图标位置没了,背景图没了,连视图模式都变回了默认。你得重新再摆一遍。

也就是说,只要一次离开苹果的地盘,你就会被惩罚。

苹果没办法让自己的付费用户接受这个情况。

所以摆在 2001 年苹果工程师面前的,其实就两个选择。

一是用 xattr。Mac 内部干净漂亮,目录里不会冒出任何多余文件。代价是 Mac 用户一旦把文件传到非 Mac 的地方,窗口记忆全丢。

二是造 .DS_Store。Mac 用户怎么传、传给谁、走什么协议、转什么格式,Finder 的记忆都跟着走。代价是其他平台的人解压时会看到一个陌生的隐藏文件。

换你选哪个?

这两个选择得罪的是不同的人。

xattr 得罪的是付钱买 Mac 的那批苹果用户。

.DS_Store 得罪的是其他平台的人,而那些人,苹果从来没从他们身上赚过钱。

所以苹果选哪个,一目了然。

而且这 25 年里,苹果其实有过好几次换方案的机会。

2007 年 iPhone 发布之后,跨平台传文件规模暴涨,.DS_Store 污染外传目录的问题第一次被大规模抱怨。苹果没动。

2011 年 iCloud 上线,云同步完全可以走独立的元数据通道,不再依赖文件系统层。苹果也没动。

2016 年苹果在 WWDC 推出全新文件系统 APFS,整个文件系统栈都被重写了一遍,这是再合适不过的换方案时机。苹果还是没动。

2020 年 Apple Silicon 架构切换,整个底层栈又重写了一遍,又是一次窗口期。.DS_Store 照旧。

每一次答案都一样。保 Mac 用户自己的体验,外人的不便,不是苹果要背的 KPI。

Mac 社区这些年其实也想了很多办法。比如 Keka 这种第三方压缩工具默认就会把 .DS_Store 去掉,zip 命令加个 -x "*.DS_Store" 参数也能过滤,给 git 配一个全局 gitignore,这台 Mac 上所有仓库就能一次性自动忽略。但下游把脏活都自己干完了,苹果反倒更没动力改。

所以那个安静躺在每一个 Mac 文件夹里的 .DS_Store,不是什么历史遗留问题。

它是苹果 2001 年就想清楚的一个选择。

下次你那个用 Windows 的同事又皱着眉删掉一堆 .DS_Store,你可以告诉他,这不是 bug。

这是苹果送给每一个 Mac 用户的一份贴心设计,而他不是苹果要讨好的那个人罢了。


署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)
位旅人路过 次翻阅 初次见面