发生这种情况是因为文件有“两个副本”(这里关于“文件”一词的术语不太准确,我不确定这里说“副本”还是“版本”更好)。一份副本是存储在机器上的实际文件文件系统 https://en.wikipedia.org/wiki/File_system(通常由某种形式的支持“外置储存” https://en.wikipedia.org/wiki/External_storage in 二级存储 https://en.wikipedia.org/wiki/Computer_data_storage#Secondary_storage),并且一个副本实际上并不是文件系统意义上的“文件”,而是在文件系统中保存和维护的“工作副本”memory https://en.wikipedia.org/wiki/Computer_memory (主存储 https://en.wikipedia.org/wiki/Computer_data_storage#Primary_storage) 分配给 VS Codeprocess https://en.wikipedia.org/wiki/Process_(computing).
The copy in memory is maintained by the VS Code process. The changes that you make as you type in the editor tab are reflected in that in-memory copy and displayed back to you in the UI. See also the TextDocument interface in the VS Code extension API https://code.visualstudio.com/api/references/vscode-api#TextDocument. VS Code (and many other text editor programs) calls the act of writing its in-memory copy to the filesystem "saving". You can find its official (brief) docs on the subject here https://code.visualstudio.com/docs/editor/codebasics#_save-auto-save. In VS Code, you can save the "file" / "text document" open in the active editor tab by pressing ctrl/cmd+s, or using the menu's File > Save item, or using File: Save
in the command palette https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette. You can also save all files using Save All
in the command palette, or ctrl/cmd+k,s. VS Code doesn't save files automatically upon every change you make to the file. You can configure it to save changes periodically with the following settings (quoting from the defaultSettings.json pseudo-file):
// Controls [auto save](https://code.visualstudio.com/docs/editor/codebasics#_save-auto-save) of editors that have unsaved changes.
// - off: An editor with changes is never automatically saved.
// - afterDelay: An editor with changes is automatically saved after the configured `files.autoSaveDelay`.
// - onFocusChange: An editor with changes is automatically saved when the editor loses focus.
// - onWindowChange: An editor with changes is automatically saved when the window loses focus.
"files.autoSave": "off",
// Controls the delay in milliseconds after which an editor with unsaved changes is saved automatically. Only applies when `files.autoSave` is set to `afterDelay`.
"files.autoSaveDelay": 1000,>
(您可能还对内置 VS Code 设置感兴趣saveBefore
在他们的 ID 中,包括task.saveBeforeRun
, debug.saveBeforeStart
, testing.saveBeforeTest
, git.promptToSaveFilesBeforeCommit
, and git.promptToSaveFilesBeforeStash
。还要检查您的扩展程序的设置,看看它们是否提供了在执行操作之前进行保存的功能,例如 CMake 工具cmake.saveBeforeBuild https://github.com/microsoft/vscode-cmake-tools/blob/main/docs/cmake-settings.md#cmake-settings).
其他程序看不到未保存的更改的原因是其他程序都有自己的更改流程 https://en.wikipedia.org/wiki/Process_(computing),并且在大多数情况下操作系统 https://en.wikipedia.org/wiki/Operating_system,每个进程都有自己的内存,进程是彼此隔离 https://en.wikipedia.org/wiki/Process_isolation由操作系统执行,其中包括阻止它们读取或写入彼此分配的内存(这有几个原因,其中安全性是一个重要原因)。因此,他们看不到 VS Code 的内存中文件副本,只能看到文件系统上的副本。为了说明这一点,当您尝试运行 shell 脚本、NodeJS 脚本、Python 脚本等时,该脚本的解释器无法看到 VS Code 内存中包含未保存更改的脚本副本 - 只能看到任何内容最后写入(“保存”)到文件系统。尝试编译/转换具有未保存更改的文件,或将未保存的更改暂存到版本控制软件(如 Git),或运行本地网络服务器从文件系统提供文件也是如此。
这是一般情况下说的。除了文件系统之外,进程之间还可以通过多种方式相互传递信息(通常取决于您的操作系统),并且提供语言支持的 VS Code 扩展可以访问内存中的内容(请参阅TextDocument
我之前链接到的 API),但他们是否选择使用该信息取决于他们(或更准确地说,是扩展的维护者)。一个非常非常基本的例子是 Python 扩展Python: Run Selection/Line in Python Terminal
和相关命令,即使在无标题文件中也可以使用。
至于新文件,如果该文件从未写入文件系统,那么现在其他程序抱怨该文件不存在的原因应该非常明显:它还不存在于文件系统中。因此,您需要保存它并为其在文件系统中指定一个要写入的位置。
对于其他不需要长时间运行的程序(例如短脚本或运行一次编译)来说,将更改写入文件系统就足够了。但对于某些用例,将更改写入文件系统不足以让其他程序使用更新的文件。如果一个程序长时间运行,例如 NodeJS 之类的 REPL,如果您使用以下命令加载了模块文件require
, 已加载的版本会被缓存在内存中 https://nodejs.org/api/modules.html#caching。您需要使用特定于程序的提供机制来让它刷新文件的缓存(例如,对于 NodeJSrequire
, see node.js require() 缓存 - 可能无效吗? https://stackoverflow.com/q/9210542/11107541),或者只是重新启动程序。或者,对于一个不同的示例,对于开发网络服务器,已由该服务器向其提供旧文件副本的客户端将不会自动了解该文件的新副本。为此,它需要向服务器发出新请求(例如,通过刷新浏览器中的页面)(并且HTTP缓存 https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching完全是“另一回事”)。
额外花絮:为什么不立即自动保存每一个小变化?
最后,您可能会问为什么不让 VS Code 在对(内存中)“文件”/“文本文档”进行每次更改后将更改写入文件系统。我不能对此做出权威的发言,但我可以给出我的一些有根据的猜测。有几个原因可能导致这种情况不理想:
-
如果您的外部存储写入速度很慢(例如磁盘驱动器往往比固态硬盘 https://en.wikipedia.org/wiki/Solid-state_drive对于写入),您将排队许多缓慢的操作,并且对操作系统的调用(通常管理用户级程序和文件系统之间的交互)有些浪费。
-
驱动器有不同的使用寿命,这会影响每个内存部分在不再工作之前可以写入的最大次数。通常有多种技术可以减轻这种情况,例如。磨损均衡/写入缓存,但是立即将每个更改写入文件系统有点过度,并且可能会缩短存储寿命。
-
这可能只是用户特定的工作流程原因。例如,如果您设置文件系统“侦听器”/“观察器”来执行诸如在源文件更改时自动重建程序或其他开发人员工具之类的操作,您可能不希望它们在每次键入字符时让任务排队。另一个例子:如何禁用颤振上的自动热重载? https://stackoverflow.com/q/61233597/11107541(而且,请参阅Flutter 热重载不适用于 VSCode 中的自动保存 https://stackoverflow.com/q/65975713/11107541).
额外花絮:VS Code 如何处理副本之间的冲突
文件系统和内存副本之间的这种分离也是为什么当您在 VS Code 之外对当前在 VS Code 中打开且未保存更改的文件写入文件系统时,VS Code 将要么
- 打开一个弹出窗口,询问“是否要保存对 所做的更改?如果不保存,您的更改将会丢失”。从该弹出窗口中,为您提供选项:“不保存”、“取消”、“保存”、
- 或者当您稍后尝试在 VS Code 中保存时,它会打开一条通知“无法保存 '':文件内容较新。请将您的版本与文件内容进行比较,或使用以下内容覆盖文件内容您的更改。”,让您可以选择覆盖文件系统副本的更改,或与文件系统副本进行比较,或关闭编辑器选项卡的隐式选项,此时它会给您前面提到的是否保存的提示关闭。