前言
很多人在使用 Office、文本编辑器、IDE 等工具时,会偶尔在文件夹里看到一个以 ~$
开头的文件;或者在异常退出后,文档被恢复为临时版本。本文将从机制出发,一步步讲清楚这个 ~$
文件的来源、作用、与缓冲机制的关联,以及为什么有时你"没保存就退出"会丢失数据。文章兼顾 Windows 与 Linux 场景,希望能对大家在日常排错、数据恢复、文件操作安全性上有帮助。
一、引子:那天看到文件夹里的 ~$xxx.docx
,我愣住了
那天我在整理一个共享文件夹,突然看到一个神秘的文件:
bash
~$报告.docx
这个文件名开头有一个波浪号加美元符号(~$
),平时看文档目录几年也没见过这个东西。
我心想:这个东西是做什么的?能删吗?会不会影响文件?
上面这正是很多开发者、文档编辑者在日常中会遇到的问题。
下面,就让我们认真梳理一遍这个 ~$
文件背后的机制。
二、~$
文件是什么?
2.1 名称与典型创建者
-
这种以
~$
开头的文件,常见于 Microsoft Office(Word、Excel、PowerPoint 等)文档目录。 -
它通常被称为 临时所有者文件(owner temp file) 或 用于锁定与恢复的临时文件。
-
在你打开一个 Office 文档(如
.docx
、.xlsx
)时,Office 会在同一目录下创建这个文件。
2.2 它的两个核心作用
作用 | 描述 |
---|---|
崩溃恢复 | 在你编辑文档的过程中,这个文件会保存你当前的编辑状态。当程序异常退出或断电时,下次打开时 Office 可以检测它,并尝试恢复未保存内容。 |
文件锁 / 协同编辑提示 | 当一个用户打开文件编辑时,~$ 文件作为"占用标志"存在。其他用户通过网络共享打开同一文档时,会检测到这个临时文件存在,从而知道该文档正被占用,可能提示以只读模式打开。 |
2.3 工作流程示意
-
用户双击
Report.docx
打开文档。 -
Office 在当前目录创建
~$Report.docx
。 -
用户开始编辑文档,此时所有修改通常是内存操作或写入缓冲区。
-
Office 会定期将编辑状态写入这个
~$
文件(或将缓冲区内容同步到临时文件)。 -
用户选"保存"或关闭文档时,Office 会把最终内容保存到
Report.docx
,然后删除~$Report.docx
。 -
如果程序崩溃或异常退出,
~$Report.docx
保留下来。下次启动 Office 时,检测到它,就认为可能有未保存数据可恢复。
如果你看到一个 ~$
文件,但原始文档是关闭状态、没有编辑者在用,那么这个 ~$
文件往往就是"残留垃圾",基本可以安全删除。
三、常见问题问答
Q1:我可以手动删除 ~$
文件吗?
回答 :是可以的。
前提是确保对应的原始文档已关闭,且没有别人在编辑。
因为在正常场景下,Office 会在关闭时自动删除这个临时文件。
如果这个文件被保留下来,一般来说它不包含额外的"核心数据",主要是编辑状态的中间快照,所以删除它不会造成文档本体的丢失。
Q2:为什么有时候看见它,有时候看不见?
-
这个文件通常是"隐藏文件"。在 Windows 资源管理器里默认是不显示隐藏文件的。
-
若文档关闭正常、Office 删除了它,你确实看不到。
-
若程序异常退出或杀死进程(崩溃、断电、强制结束),
~$
文件可能没有被清理,下一次就能看到。
Q3:其他程序也会创建类似的文件吗?
当然会。虽说命名习惯不同,但原理类似。下面是几个例子:
-
文本编辑器 Vim:会创建以
.filename.swp
的交换(swap)文件。 -
Emacs:会生成以
#filename#
的自动保存文件。 -
LibreOffice(或 OpenOffice):通常把临时及恢复文件放在用户缓存目录中,而不是文档目录。
-
各种 IDE、编辑器也有自己的自动保存机制,比如
.autosave
格式、临时文件、回收站版本等。
这些程序之所以都这么做,是出于同一个目的:在意外结束时,尽可能保留可恢复状态。
四、Linux 环境下的情况:有没有 ~$
文件?
这个问题很有意义,因为很多人在 Windows 和 Linux 混用环境。
4.1 在 Linux 上运行 Office(例如通过 Wine)
如果你通过 Wine、CrossOver 等在 Linux 下运行 Microsoft Office,那么 Office 的行为在文档目录创建 ~$
文件的机制是与 Windows 一致的。也就是说,你很可能在 Linux 的文档目录看到 ~$Report.docx
------Office 在写 Linux 上也会做同样的操作。
4.2 Linux 原生程序的临时 / 自动保存机制
Linux 本身不会强制为每个编辑的文件生成 ~$
文件。各个程序有各自机制,常见做法如下:
-
临时目录集中化 :许多程序把临时文件放在
/tmp
或/var/tmp
,而不是文档目录。这样目录不会被凌乱。 -
隐藏文件命名 :有些程序直接在文档目录创建以
.
开头的隐藏文件(如.filename.swp
)。 -
用户目录下保存 :LibreOffice 在 Linux 上通常把恢复数据写到
~/.config/libreoffice/.../backup
等路径,而不是文档目录本身。 -
编辑器交换 / 自动保存机制 :例如 Vim 的
.swp
、Emacs 的#...#
,都在编辑期间存在,正常退出会删除或重命名。
下面是一个对比表格:
环境 / 程序 | 临时或恢复文件命名 | 存放位置 | 核心用途 |
---|---|---|---|
Microsoft Office(在 Windows 或 Wine 上) | ~$文件名 |
与文档同一目录 | 崩溃恢复 + 文件锁 |
Vim | .filename.swp |
与文档目录 | 崩溃恢复 +占用检测 |
Emacs | #filename# |
与文档目录 | 自动保存 |
LibreOffice | 随机名或隐藏文件 | 用户配置目录 / 缓存目录 | 自动恢复 /临时备份 |
其他编辑器 / IDE | .autosave 、~filename.tmp 等 |
文档目录或临时目录 | 临时保存 /回滚功能 |
综上,Linux 下虽然默认不产生 ~$
文件,但多数应用程序有自己的备份、自动保存、恢复机制。命名、存放方式更加多样,更倾向于"幕后隐藏"的方式,而非直接出现在当前目录。
五、缓冲机制与 I/O 写入:关键关联
要理解为什么"没点保存,直接退出"会导致数据丢失,就必须理解 缓冲机制 。~$
文件只是机制的一环,缓冲机制是更基础的技术层面。
5.1 缓冲的意义
磁盘 I/O 要比内存慢得多。若每次微小变化就写磁盘,会极度损耗性能。
缓冲机制提供一个"中转仓库",把多次小写入合并成一次大写入,从而提高效率。
在现代系统里,这个缓冲机制分为两个层次:
-
用户级缓冲(用户空间)
程序库(如 C 标准库、应用层)会把小量写操作先写入用户空间缓冲区。
-
内核级缓冲(操作系统内核)
用户空间把缓冲内容提交给操作系统后,OS 会将其放入自己的缓冲队列,稍后统一写入物理磁盘(或根据策略延迟写入)。
只有当这两个缓冲都刷新 / 写入到磁盘后,数据才真正落盘持久化。
5.2 三种缓冲模式
模式 | 触发写入条件 | 典型用途 | 特点 / 风险 |
---|---|---|---|
全缓冲(Fully Buffered) | 缓冲区满、手动 flush、关闭文件 | 文件 I/O | 高效,但若未 flush,退出时会丢失数据 |
行缓冲(Line Buffered) | 遇到换行符 \n 或缓冲满 |
标准输出 / 交互式 I/O | 对终端输出很友好 |
无缓冲(Unbuffered) | 每次写操作立刻执行 | 错误输出、日志流 | 实时性好,但性能代价高 |
在 C / C++ 标准库中,默认文件 I/O(fopen
、fwrite
等)通常使用 全缓冲 。也就是说,只有缓冲区满了、遇到 fflush()
、fclose()
等操作时才写入系统。若你在这之前程序崩溃或退出,那些还没 flush 的数据就丢了。
标准 I/O 函数中:
-
fflush(FILE *stream)
:强制刷新该流的缓冲区(用户空间 → 内核空间)。 -
fclose(FILE *stream)
:关闭流之前,会自动刷新缓冲区。 -
setvbuf
/setbuf
:可以设置缓冲模式(全缓冲 / 行缓冲 / 无缓冲)和缓冲区大小。
5.3 "保存"操作的真实含义
当我们在应用程序(如 Office、文本编辑器)里点击"保存"按钮时,底层实际上执行的就是:
-
把用户缓冲区的数据 flush 到内核缓冲区;
-
操作系统最终承担将内核缓冲区内容写入磁盘;
-
删除临时
~$
文件(如果有)或清理恢复状态。
如果我们没有点击"保存",数据仍可能停留在用户缓冲区或内核缓冲区里,还未真正落盘。当程序崩溃或被强制终止时,这些缓冲还未完成写操作,数据就丢失。
六、一个完整案例剖析:写文本编辑器那一刻的数据流
下面我们来画一个流程图 / 步骤,便于理解每个阶段的数据状态,以及各类故障时数据如何丢失 / 恢复。
6.1 正常编辑、保存流程
[用户输入] → 写入用户缓冲区 → (定期或手动)→ flush 到内核缓冲区 → 操作系统异步写入磁盘 → 删除 "~$" 临时文件
补充一点:编辑期间还可能写入 ~$
临时文件做恢复状态记录(写入临时文件通常也涉及缓冲机制)。
6.2 异常退出 / 崩溃流程
[用户输入] → 写入用户缓冲区 → (尚未 flush)→ 程序崩溃 / 强制退出 → 用户缓冲区数据被释放 → 内核缓冲区可能尚未写入磁盘 → 原文档和 `~$` 文件状态可能不一致 → 下次启动可根据 `~$` 文件尝试恢复部分内容
在这种异常情形下,~$
文件成为你恢复恢复点的依据;它记录了最近一次写入临时状态的情况。
6.3 为什么"没保存就退出"导致丢失?
因为在全缓冲机制下,很多修改都还停留在用户缓冲区,不会自动 flush。
若程序没有机会执行刷新操作(因为被强制终止),这些缓冲数据就永远消失了。
你可以把"点击保存"理解为给程序下达命令:"把当前所有未写入磁盘的数据都写下来。"在程序没有执行这条命令之前,就退出、崩溃,就没机会写入,资料残留在缓冲区。
七、实用建议与注意事项(程序员视角)
在理解底层机制后,我们来看一些实际建议,帮助减少数据丢失风险、优化文件操作安全性。
7.1 编辑器 / 文档使用端的行为建议
-
勤保存:尤其在编辑重要文档时,手动点击"保存"比依赖自动保存要安全。
-
开启自动保存 /备份功能:现代编辑器(VS Code、Office 等)通常有自动保存、定时备份、版本历史等功能,应合理配置。
-
退出前确认保存:在关闭程序或文档前,确保有保存提示机制,避免误关闭。
-
定期检查临时文件残留 :若目录里常见
~$
文件残留,可能说明程序曾异常退出,建议及时清理或恢复。
7.2 程序 / 库 /工具开发者视角
如果你在编写涉及文件写入的程序,可以考虑以下策略:
-
在关键写操作完成后,调用
fflush()
、fsync()
等保证写入。 -
对异常情况做捕获与清理机制(try / finally /析构流程),确保 flush 与关闭。
-
在锁定 / 协作场景下,也可用类似
~$
机制标识文件被占用。 -
对于长时间编辑或关键数据,设计自动保存 /增量快照机制。
-
在跨平台或多系统上操作文件时,要考虑临时文件命名规范、权限控制、安全清理等细节。
八、个人观点与总结
从我平常处理文档、编辑器、文件存储的经验来看,这个 ~$
文件机制虽然看起来神秘,但其实是一个非常务实、典型的"中间保护层"设计。它并不是专为 Office 孤立设计,而是这一类软件在面临崩溃、并发访问、恢复机制等挑战时的一种通用解决方案。
下面是我对这几个层面的总结与看法:
-
设计的取舍
Office 选择在文档目录生成
~$
文件,是为了简单直观,让恢复机制紧贴文档本身。缺点是目录易被污染、误删可能造成恢复困难。这种设计在桌面办公场景下,是一种合适的折中。 -
自动恢复 vs 程序稳定性
~$
文件机制并不能替代良好的保存策略。如果一个编辑器频繁崩溃,即便有~$
也可能恢复不完整。核心还是软件自身的稳定性、自动保存频率、错误处理机制。 -
缓冲机制是根基
在我看来,很多人把"没保存就退出丢失"归罪于 Office、文档编辑器,实际上根源在于 I/O 缓冲机制及其触发机制。如果开发者、用户对这一机制有基本理解,就会更安全地操作。
-
跨平台设计要兼顾一致性
在跨系统应用中(Windows / Linux / macOS),临时文件机制通常要设计为可配置、命名可控、易恢复、易清理。不能假设都会生成
~$
或.swp
,也不能假设临时目录永远可用。