标签 Finder 下的文章

本文希望从 .DS_Store 出发,基于与 Windows 平台下的类似文件 Desktop.ini 和 Thumbs.db 的对比,论述 Finder 与 Windows 资源管理器在某些设计方面的差异。


你是否在 Windows 与 macOS 之间频繁切换工作、互传数据?你是否拥有 NAS 并且局域网内同时存在 Mac 和 PC 访问其资源?或者,你是否拥有一位使用 Mac 的朋友、同事、同学,并使用储存介质在他们的 Mac 上拷贝过文件?如果满足上述任一条件,那么你应该大概率见过 .DS_Store 文件。

如果你进入互联网搜索 .DS_Store 文件,扑面而来的却可能是大量「讨伐」.DS_Store 的声音。主流的搜索结果包括「如何删除 .DS_Store 文件」「如何阻止 .DS_Store 生成」「如何在项目/仓库中排除 .DS_Store」「.DS_Store 文件清理工具」等等。

可以说,大多数搜索结果以及针对 .DS_Store 的批评意见其,实围绕着 .DS_Store 文件本身展开,而「.DS_Store」与产生这一文件的 macOS Finder 之间的关联却常常被人忽视。抛开 Finder 谈 .DS_Store 就如同抛开前提条件谈问题——在很大程度上失去讨论问题的意义。

因此,本文希望从 .DS_Store 出发,基于与 Windows 平台下的类似文件 Desktop.ini 和 Thumbs.db 的对比,论述 Finder 与 Windows 资源管理器在某些设计方面的差异。

概述

在开始 macOS 的 Finder 与 Windows 资源管理器的比较前,这里还是有必要对本文将要讨论的几个对象做出简要概述。

首先是 .DS_Store 文件,其英文全称为 Desktop Services Store(桌面服务存储),诞生于 1999 年 Mac OS X Finder 重写时期。这是一种由 macOS 自动创建的隐藏文件,本质上是一个采用 B-树(B-tree)结构的专有二进制文件。它主要用于存储 Finder 文件夹的自定义属性与元数据,这些数据通常无法直接由文件系统本身记录,例如用于记录图标位置的 Iloc、用于存储 Finder 注释(Finder Comments)的 cmmt、以及文件夹背景图片 BKGD 等。

第二是 Desktop.ini 文件。这是一种隐藏的受保护 Windows 系统配置文件 (*.ini)。它用于存储所在文件夹的自定义设置,包括图标、显示名称 (本地化名称) 或文件夹说明等。

最后是 Thumbs.db 文件。Thumbs(缩写自 thumbnails)即缩略图数据库,这是一种 Windows 系统文件,采用 OLE 复合文档结构。它用于储存文件夹中图像和视频的缩略图预览缓存,以加速 Windows 资源管理器对缩略图的加载。

可见,在 Windows 中,功能设计上与 .DS_Store 更相近的则应该是 Desktop.ini(尽管它的出现频率没有 Thumbs.db 那么高)。

基础差异比较

既然 Windows 中也有 Desktop.ini 与 .DS_Store,那么为什么对于移除 .DS_Store 的需求更为突出,甚至视其为垃圾文件呢?这里笔者认为主要有以下几点因素,包括生成策略以及隐藏文件策略的差异。

生成策略

生成策略直接决定了文件是否会频繁出现。虽然 Apple 并未公开其完整技术文档,但根据日常观察和逆向工程的研究,.DS_Store 的生成策略极为激进。

一方面,.DS_Store 是跟随文件夹的,每个文件夹都会产生自己的 .DS_Store。

另一方面,打开文件夹、修改视图、排列、文件夹窗口大小和位置等大多数操作都有可能触发文件夹下 .DS_Store 的生成。

(一些例外情况包括:在仅包含文件而不存在次级文件夹目录的文件夹中调整设置并不会使 .DS_Store 生成;在部分采用非日志式文件系统的外置存储介质上,调整文件夹的配置不会生成 .DS_Store。)

相比之下,Desktop.ini 文件虽然也是跟随文件夹的,但其生成策略要保守得多。

根据日常观察,Desktop.ini 主要常见于用户目录下几个系统预置的文件夹中,如桌面、下载、文档等。这是因为 Windows 为这些特殊文件夹定制了图标和本地化名称,必须通过 Desktop.ini 记录。

而在普通文件夹中,单纯修改视图或排列方式往往不会生成 Desktop.ini——Windows 资源管理器似乎更倾向于在注册表或系统盘的特定位置中心化地存储这些配置。因此,普通用户在日常文件操作中遇到 Desktop.ini 的频率远低于 .DS_Store。

某个 Desktop.ini 文件中记录的信息

至于 Thumbs.db,在 Windows 早期版本中确实随文件夹存储,但自 Windows Vista 起,缩略图缓存已被改为中心化存储在用户的 AppData 目录下(文件名为 thumbcache_xxx.db)。这一改变使得该文件淡出了普通用户的视野。

上述目录与其中的文件

隐藏文件策略

隐藏文件的展示策略也是影响用户感知的关键因素。macOS 默认不显示以点号开头的文件,而在 Windows 上,用户开启「显示隐藏文件」后即可看到 .DS_Store。但「显示隐藏文件」并不会展示 Desktop.ini,因为后者还被标记为「受保护的操作系统文件」,需要更深层级的设置才能取消隐藏。因此,如果用户经常在 macOS 与 Windows 间交换数据,对 .DS_Store 文件的感知还会更加强烈。

二次确认对话框
ls -a 呈现的目录下所有项目

设计差异比较

然而,要正确评价 .DS_Store 或是 Desktop.ini,我们不可能脱离产生它们的平台孤立地看待问题,而是要落脚到 macOS 访达与 Windows 资源管理器的设计哲学比较上。

Windows 的资源管理器是一个有边界的、强调秩序的内容呈现窗口。在窗口内,所有内容均强制按照某种特定的顺序(如名称、日期、类型)排列,并严格对齐网格。资源管理器仅有一个例外,那就是桌面。只有在桌面上同时取消「自动排列图标」和「将图标与网格对齐」后,图标才可以像画布一样自由放置。

这种设计导致 Windows 文件夹在拷贝到另一台电脑时,虽然会丢失视图配置,但也保证了文件夹状态的「相对干净」和展示逻辑的统一性。

会员专属文章,欢迎加入少数派会员。

优质内容

权益周边

会员社群

power+

起源

发帖求助后,自己细想想应该有工具可以往右键添加操作,不想下载新 App,检索对比 Automator.app 和 Shortcuts.app 后决定还是使用 Shortcuts.app 搭配 AppleScript 来实现我要的操作。

脚本

-- 辅助函数:去除字符串首尾的空格、制表符、换行等空白字符
on trimText(theString)
	if theString is "" then return theString
	
	-- 使用非保留字的变量名:trimStart / trimEnd
	set trimStart to 1
	repeat while trimStart ≤ length of theString and character trimStart of theString is in {" ", tab, return, linefeed}
		set trimStart to trimStart + 1
	end repeat
	
	if trimStart > length of theString then return ""
	
	set trimEnd to length of theString
	repeat while trimEnd ≥ trimStart and character trimEnd of theString is in {" ", tab, return, linefeed}
		set trimEnd to trimEnd - 1
	end repeat
	
	return text trimStart thru trimEnd of theString
end trimText

-- 获取 Finder 当前窗口的位置
tell application "Finder"
	set currentPath to insertion location as alias
end tell

-- 弹出对话框,提示用户输入文件名,默认为“Untitled.txt”
set defaultName to "Untitled.txt"
set userInput to text returned of (display dialog "请输入新文件的名称:" default answer defaultName with title "创建新文件")

-- 清理用户输入:去除首尾空白
set fileName to my trimText(userInput)

-- 如果用户什么都没输(或只输空格),则使用默认文件名
if fileName is "" then set fileName to defaultName

-- 智能处理扩展名:
-- 情况1:文件名中不含“.”,或者以“.”开头(如“.gitignore”),则添加 .txt
-- 情况2:文件名以“.”结尾(如“笔记.”),则补全为“.txt”
if fileName does not contain "." or fileName begins with "." then
	set fileName to fileName & ".txt"
else if last character of fileName is "." then
	set fileName to fileName & "txt"
end if

-- 检查是否已存在同名文件,若存在则自动添加编号(如“文件 1.txt”)
tell application "Finder"
	set baseName to fileName
	set counter to 1
	
	-- 从文件名末尾查找第一个“.”,正确分离主文件名和扩展名
	set revChars to reverse of characters of fileName as string
	set dotIndex to offset of "." in revChars
	
	if dotIndex = 0 then
		-- 理论上不会发生(前面已处理无扩展名情况),但保留安全兜底
		set namePart to fileName
		set fileExt to ""
	else
		-- 提取扩展名(如“txt”)和主文件名(如“报告”)
		set fileExt to reverse of (characters 1 through (dotIndex - 1) of revChars) as string
		set namePart to text 1 thru -(dotIndex + 1) of fileName
	end if
	
	-- 循环检查文件是否存在,若存在则生成带编号的新文件名
	set fileName to baseName
	repeat while (exists file ((currentPath as text) & fileName))
		if fileExt is "" then
			set fileName to namePart & " " & counter
		else
			set fileName to namePart & " " & counter & "." & fileExt
		end if
		set counter to counter + 1
	end repeat
	
	-- 在当前目录创建新文件,并在 Finder 中高亮显示
	set newFile to make new file at currentPath with properties {name:fileName}
	reveal newFile
end tell

AIGC 声明:本脚部分函数由 通义千问 辅助创造,本人已验证其生成内容的真实性和有效性

使用方法

我也是第一次接触 AppleScript ,考虑可能有其他佬友也未接触使用过,特贴出使用方法

  1. 打开 Shortcuts.app
  2. 如果你是首次使用,请按⌘ + , 打开设置中的高级-允许使用脚本
  3. 新建快捷指令
  4. 设置基本信息
  5. 添加 AppleScript
  6. 在 Finder 中使用

参考文献

AppleScript 开发文档
AppleScript 入门:探索 macOS 自动化 - 少数派


如果有帮到你,还请给我投两个 LDC 吧!
或者请我喝杯咖啡

都不想的话请点个免费的也好


📌 转载信息
原作者:
LeonShaw
转载时间:
2026/1/24 06:32:36