recover.txt 适用于 Vim 9.2 版本。 最近更新: 2026年7月
VIM 参考手册 by Bram Moolenaar
译者: iCrazy<icrazy@ustc.edu>、tocer
从崩溃中恢复 crash-recovery
您经历过这样的事情么?录入一个文档,花了很长时间,眼看就要完成的时候,灾难来临
了: 电脑崩溃了!
别 担 心 !
可以从 Vim 提供的文件里恢复大部分的改动,Vim 用这些文件保存文件的内容。一般情
况下,用单个命令就可以恢复文档:
vim -r filename
1. 交换文件 swap-file
2. 恢复 recovery
Vim 把文件改动存入交换文件。结合修改前的原始文件和交换文件,丢失的改动基本都能
恢复。
可用以下命令查看当前交换文件名:
:sw[apname] :sw :swapname
也可使用 swapname() 函数,可同时看到其他缓冲区的交换文件名。
交换文件默认与编辑文件同名,只是扩展名换成了 ".swp"。
- 在 Unix 系统上,交换文件与原始文件同目录、且文件名开头加 '.',此类文件在目录
列表里缺省隐藏显示。
- 在 MS-Windows 系统上,'shortname' 选项打开时,原始文件名中所有 '.' 会被 '_'
替代。
- 如果同名交换文件已存在 (如刚从崩溃后恢复时),Vim 会显示警告,并自动更换扩展
名,如 ".swo",".swn" 等。
- 永远不会覆盖已有交换文件。
- Vim 正常停止编辑文件时,会自动删除交换文件。
技术细节: 用 '_' 替代 '.' 是为了避免在 MS-DOS 兼容文件系统 (crossdos、multidos
等) 上出现问题。Vim 检测到编辑文件位于 MS-DOS 兼容文件系统时,自动置
位 'shortname' 选项等效的内部标志位。编辑其他文件时该标志位会重置。
E326
扩展名为 ".swp" 的文件已存在时,逐次递减末位字母,直到没有冲突为止。
如果过了 ".saa" 还找不到,不再创建交换文件。
通过设置 'directory' 选项,可将交换文件放在其他目录,而不是缺省的原始文件所在
目录。
优点:
- 不会因为 ".swp" 文件的存在弄乱目录。
- 'directory' 放在其他磁盘分区时,系统崩溃时能降低原始文件所在分区文件系统损坏
的风险。
缺点:
- 不同目录下同名文件会产生文件名冲突 (Vim 会尝试对比文件路径以避免此问题)。这
会导致虚假 ATTENTION 警告信息。
- 如果交换文件放在用户主目录下,而其他用户试图编辑相同文件时,该用户无法访问他
人主目录下的交换文件,此时不会出现 ATTENTION 警告信息。
在 Amiga 系统上,还可使用断电可恢复的内存盘,但无法百分百保证恢复有效。
不要将交换文件放到普通内存盘 (如 Amiga 的 RAM:) 或重启清空的临时目录 (如 Unix
上的 /tmp 目录),一旦崩溃交换文件会直接丢失。
要使用固定目录存放交换文件,可在 .vimrc 中加入:
:set dir=dh2:tmp (针对 Amiga)
:set dir=~/tmp (针对 Unix)
:set dir=c:\\tmp (针对 Win32)
这对编辑软盘上的文件十分便利。当然必须先提前建立好该 "tmp" 目录。
Vim 通常不会为只读文件生成交换文件,但有例外,当文件体积过大,使得占用内存超出
'maxmem' 或 'maxmemtot' 值时,会创建交换文件。当只读文件被修改时,也会如此。
可复位 'swapfile' 选项禁用交换文件。 :noswapfile 修饰符也可使新缓冲区不建立交
换文件。
:nos[wapfile] {command} :nos :noswapfile
执行 {command}。该命令包含加载新缓冲区操作时,加载时不创建交换
文件,并复位 'swapfile' 选项。缓冲区已有交换文件时,不会自动删
除,也不会复位 'swapfile'。
检测到交换文件存在
相关内容详见用户手册 11.3 一节。
更新交换文件
录入 200 个字符后、或 4 秒内没有录入任何字符时,交换文件会被自动更新。更新仅在
缓冲区已修改时才会进行,单纯移动光标不会。为什么不实时更新?因为频繁更新会极大
拖慢其他正常工作。可通过 'updatecount' 选项修改 200 字符阈值,或通过
'updatetime' 选项修改 4 秒超时 (以毫秒为单位)。
Vim 更新交换文件后,会将文件同步到磁盘。这会消耗相当时间,在忙碌的 Unix 系统上
尤其如此。如果不希望这样,可将 'swapsync' 选项置成空串。但这会大幅提升崩溃丢失
修改的风险。在部分非 Unix 系统 (MS-Windows、Amiga) 上,不会执行磁盘同步。
将 'updatecount' 选项设为 0 或用 -n 选项启动 Vim 可完全停止写入交换文件。
重新将 'updatecount' 选项设为非 0 值即可恢复。后续所有缓冲区都会生成交换文件。
但 'updatecount' 设为 0 仅对新打开的文件生效,已存在的交换文件不会被删除。
要手动把全部修改写入交换文件,可用以下命令:
:pre :preserve E313 E314
:pre[serve] 将当前缓冲区全部文本写入交换文件。恢复时不再依赖原始文
件。本命令会在当前缓冲区设置内部标志位,标记为 "已保留
交换文件"。
'cpoptions' 里包含 '&' 标志位 ( cpo-& ),Vim 退出且此
缓冲区仍处于加载状态时,不会删除此缓冲区的交换文件。
Vim 交换文件开头固定六个字符为 "b0VIM " (可用于识别)。其后紧跟 Vim 版本号 (如:
3.0)。
链接和符号链接
Unix 上同一文件可拥有两个名字。这可以通过硬链接和符号链接 (symlink) 完成。
对于硬链接,Vim 无法识别该文件的其他名称。所以,交换文件名基于用户提供的编辑文
件名。也不会检查是否通过其他名称访问同一文件,因为 Vim 无法找到另一个交换文件
(除非全盘查找,但耗时显然无法承受)。
对于符号链接,Vim 会自动解析链接识别真实文件名。交换文件名基于真实文件名,所以
无论用哪个名字编辑,交换文件名通常保持唯一。但有若干例外:
- 如果真实文件所在目录不可写,交换文件会放在别处。
- 如果符号链接因某种原因形成循环,会报错 E773 ,并使用未解析的原始链接名,文
件将无法正常保存。
基本文件恢复功能请参考用户手册: usr_11.txt (启动 Vim 时带参数 -r )。
另一种恢复方式是在启动 Vim 后使用以下命令。用 Vim 编辑文件并弹出提示 "注意: 发
现交换文件 …" 时,直接不带参数执行本命令即可完成恢复。也可显式指定原始文件名
或交换文件名:
:rec :recover E305 E306 E307
:rec[over] [file] 尝试从交换文件恢复 [file]。[file] 省略时,使用当前缓冲
区文件名。执行后缓冲区原有内容会丢失。如果缓冲区已修
改,本命令会失败。
:rec[over]! [file] 类似 ":recover",但强制覆盖,丢弃当前缓冲区中所有未保
存修改。
E312 E309 E310 E1364
在交换文件存在损坏时,Vim 会做智能容错处理。如果 Vim 无法确定读取内容合法性,
会报错,并在文本中插入含有带 "???" 标记的行。如果恢复时看到了出错信息,请在文
件中查找 "???" 定位损坏丢失内容段。按需剪贴保留可用文本。
最常见的信息是 "???缺少了一些行"。代表 Vim 无法读取原始文件相应文本。通常是因
为系统崩溃而导致原始文件部分内容无法及时写入磁盘。
覆盖原始文件并删除交换文件前,务必确认恢复内容正确完整。建议先将恢复后的内容另
存其他路径,通过 'diff' 进行比较,确定需要的修改均已恢复。也可直接执行
:DiffOrig 比较原始文件与恢复内容。
确认恢复成功后,请删除交换文件。否则,下次打开文件会持续弹出 ".swp" 文件已存在
的警告信息。
注意: 通过交换文件恢复只能尽力而为。Vim 会试图校验字段,跳过损坏部分,但交换文
件格式仅为可信文件设计。刻意编写的交换文件不难触发解析器漏洞;此类报告会作为健
壮性问题而非安全性问题处理。
加 密 和 交 换 文 件 :recover-crypt
文件开启加密时,交换文件也会同步加密。恢复流程会稍微复杂一些。从加密交换文件恢
复时,需要输入一到两次加密密钥。
原始文件已丢失时,只需输入密钥一次,解密交换文件。
原始文件仍存在时,与交换文件可能使用不同密钥。会分两次提示输入密钥:
"/tmp/tt" 需要密码
输入密码: ******
"/tmp/tt" [已加密] 23200L, 522129C
使用交换文件 "/tmp/.tt.swp"
原始文件 "/tmp/tt"
交换文件已被加密:"/tmp/.tt.swp"
如果你输入了新密码但是没有保存此文本文件,
输入新密码:
如果你更改密码后保存了此文本文件,请按回车键
来对文本文件和交换文件使用同一密码
输入密码:
对应两种实际情况:
1. 密钥从未修改,或修改后才写入文本文件。会有两次密钥输入提示。第二次直接按回
车即可。代表原始文件和交换文件共用同一密钥。
2. 更换新密钥后,未执行保存。Vim 会使用新密钥加密交换文件,但原始文件仍用旧密
钥加密。第二次提示应输入新密钥。
注意 恢复完成后,文件会沿用交换文件密钥。后续保存文件时,需使用新密钥打开。
vim:tw=78:ts=8:noet:ft=help:norl: