关于.app包kMDItemPhysicalSize属性的来源与空值问题咨询
背景
我正在开发一款Mac工具,使用mdfind -attr kMDItemPhysicalSize快速获取/Applications目录下.app包的大小参考值。在macOS 15.x设备上的测试结果:
- 100款应用中87款返回有效值(如Bitwarden:916 MB,Docker:2.4 GB,Safari:37 MB);
- 13款大型或频繁更新的应用(如Xcode、Brave Browser等)始终返回
(null)。
通过mdimport -t -d2测试发现,Application.mdimporter不为任何.app包生成kMDItemPhysicalSize等大小相关属性,但mdls仍能为87%的应用返回该值,说明Spotlight栈中存在独立于导入器的子系统负责填充该属性。
已完成的测试:排除文件系统问题、重新导入不填充属性、强制导入可刷新有效值等,确认应用导入器不负责处理包大小。
我的猜想:
Application.mdimporter处理.app包时生成显示名称等元数据;mds或其助手单独递归计算包大小并写入kMDItemPhysicalSize;- 大型/频繁更新包会跳过此步骤,导致属性为空。
疑问
- 哪个子系统负责为.app包填充kMDItem*Size属性?
- 跳过大型/频繁更新包的逻辑是否有文档说明?
- 是否有官方方法让Spotlight重新计算缺失的属性?
解答
1. 负责填充kMDItem*Size属性的子系统
Spotlight的核心索引服务mds(Metadata Server)及其附属的mds_stores进程是计算并填充文件/包大小类元数据(包括kMDItemPhysicalSize、kMDItemLogicalSize)的核心组件。这类属性不属于特定文件类型导入器(如Application.mdimporter)的处理范畴,而是由mds在索引过程中,通过遍历文件系统实体内容计算后写入元数据数据库。
Application.mdimporter仅专注于.app包的类型识别、显示名称、版本信息等应用专属元数据,不涉及大小计算。
2. 跳过大型/频繁更新包的逻辑文档
苹果并未公开Spotlight针对大型或频繁更新文件/包的索引优化细节,包括跳过大小计算的具体规则。从实际测试和社区经验来看,这类逻辑是Spotlight为平衡索引性能与资源消耗设计的启发式规则:
- 对于Xcode这类多GB级别的超大型包,递归计算大小会消耗大量CPU和I/O资源,
mds会优先跳过以保证整体索引效率; - 对于Brave这类自动更新频繁的应用,重复计算大小会导致索引频繁波动,
mds会选择延迟或跳过该属性的更新。
3. 强制Spotlight重新计算缺失属性的官方方法
可以通过以下官方命令触发目标.app包的元数据重新计算:
- 重置单个应用的索引:
先关闭目标路径的索引,再重新开启,会强制mdutil -i off /Applications/TargetApp.app mdutil -i on /Applications/TargetApp.appmds重新遍历该包并计算所有元数据(包括大小属性)。 - 强制重新导入元数据:
mdimport -r /Applications/TargetApp.app-r参数会强制重新导入目标文件/包,触发mds重新计算相关属性。 - 重建整个系统索引:
此命令会重建整个系统的Spotlight索引,耗时较长,但能彻底解决大量缺失属性的问题。mdutil -E /
注意:对于超大型应用(如Xcode),即使执行上述命令,mds仍可能因性能考量跳过大小计算,此时建议直接通过du命令获取准确大小:
du -sh /Applications/Xcode.app
内容的提问来源于stack exchange,提问作者Stofke

