34.10.2 编码与输入输出

编码系统的主要用途是读写文件。 函数 insert-file-contents 使用编码系统解码文件数据, write-region 使用编码系统编码缓冲区内容。

你可以显式指定要使用的编码系统 (see 为单次操作指定编码系统),也可通过默认机制隐式指定 (see 默认编码系统)。但这些方式可能无法完全确定具体的处理方式。 例如,它们可能会选择 undecided 这类编码系统,此类编码系统会根据数据来确定字符编码转换方式。 在这些情况下,输入输出(I/O)操作会最终完成编码系统的选择工作。 你通常会希望在操作完成后获知实际选用的是哪一种编码系统。

Variable: buffer-file-coding-system

这个缓冲区局部变量记录了保存缓冲区以及使用 write-region 写入缓冲区部分内容时所使用的编码系统。 如果待写入的文本无法通过该变量指定的编码系统安全编码,这些操作会调用 select-safe-coding-system 函数 (see 用户选择的编码系统s) 来选择一种备选编码。 如果选择其他编码需要让用户指定编码系统, buffer-file-coding-system 会更新为新选定的编码系统。

buffer-file-coding-system 不会影响向子进程发送文本的操作。

Variable: save-buffer-coding-system

该变量用于指定保存缓冲区时使用的编码系统(会覆盖 buffer-file-coding-system 的值)。 请注意,该变量不适用于 write-region 操作。

当保存缓冲区的命令初始打算使用 buffer-file-coding-system(或 save-buffer-coding-system), 而该编码系统无法处理缓冲区中的实际文本时, 该命令会调用 select-safe-coding-system 让用户选择另一种编码系统。 完成选择后,该命令还会将 buffer-file-coding-system 更新为用户指定的编码系统。

Variable: last-coding-system-used

文件和子进程的输入输出(I/O)操作会将该变量设置为实际使用的编码系统名称。 显式的编码和解码函数 (see 显式编码与解码) 也会设置该变量。

警告: 由于接收子进程输出会修改该变量的值, 每当 Emacs 进入等待状态时,该变量都可能发生变化; 因此,你应当在执行完存储目标值的函数调用后立即复制该变量的值。

变量 selection-coding-system 指定了为窗口系统编码选区内容的方式。See 窗口系统选择

Variable: file-name-coding-system

变量 file-name-coding-system 指定了用于编码文件名的编码系统。 Emacs 在所有文件操作中都会使用该编码系统对文件名进行编码。 如果 file-name-coding-system 的值为 nil, Emacs 会使用由选定的语言环境决定的默认编码系统。 在默认语言环境下,文件名中的所有非 ASCII 字符都不会进行特殊编码; 这些字符会以 Emacs 内部表示形式出现在文件系统中。

警告: 如果你在 Emacs 会话过程中修改 file-name-coding-system(或语言环境), 对于那些已经打开、且文件名是按照旧编码系统编码的文件, 在新编码系统下的处理方式可能不同,从而引发问题。 如果你尝试使用原来的文件名保存这些缓冲区中的某一个, 保存操作可能会使用错误的文件名,或者触发错误。 如果发生此类问题,请使用 C-x C-w 为该缓冲区指定一个新的文件名。

在 Windows 2000 及更高版本的系统中,Emacs 默认使用 Unicode API 向操作系统传递文件名, 因此 file-name-coding-system 的值在很大程度上会被忽略。 当 system-type 的值为 windows-nt 时, 需要在 Lisp 层对文件名进行编码或解码的 Lisp 应用程序应当使用 utf-8 编码系统; 将 UTF-8 编码的文件名转换为适合与操作系统通信的编码这一过程,由 Emacs 在内部完成。