将文件内容复制到缓冲区,可使用函数 insert-file-contents。(Lisp 程序中请勿使用命令 insert-file,该命令会设置标记。)
该函数在当前缓冲区的点后插入文件 filename 的内容,返回包含文件绝对路径与插入数据长度的列表。若 filename 不是可读文件,则抛出错误。
该函数会根据预设文件格式检查并转换文件内容,同时调用 after-insert-file-functions 列表中的函数。See 文件格式转换。通常,列表中的某一函数会确定解码文件内容所用的编码系统(see Coding Systems),包括行尾转换。但若文件包含空字节,默认情况下访问时不执行任何编码转换。See inhibit-null-byte-detection。
若 visit 非 nil,该函数会额外将缓冲区标记为未修改,并设置缓冲区相关字段使其关联文件 filename,包括缓冲区访问文件名与上次保存的文件修改时间。该功能由 find-file-noselect 使用,一般不建议直接调用。
若 beg 与 end 非空,应为字节偏移量,指定插入文件的片段;此时 visit 必须为 nil。例如:
(insert-file-contents filename nil 0 500)
会插入文件前 500 字节对应的字符内容。
若 beg 或 end 落在字符多字节序列中间,Emacs 的字符编码转换会向缓冲区插入一个或多个 8 位字符(又称 “原始字节(raw bytes)”)(see Character Sets)。若需以此方式读取文件片段,建议在调用该函数时将 coding-system-for-read 绑定为合适的值(see Specifying a Coding System for One Operation),并编写代码检查边界处的原始字节,读取完整字节序列后转换为合法字符。
若参数 replace 非 nil,表示用文件内容替换缓冲区(实际为可访问区域)内容。该方式优于先删除再整体插入,原因在于:1)保留部分标记位置;2)减少撤销记录中的数据量。
insert-file-contents 可读取特殊文件(如管道、I/O 设备),条件是 replace 为 nil 或 if-regular,且 visit 与 beg 为 nil。但此类文件通常需指定 end 参数,避免向缓冲区插入无限长度数据(例如读取 /dev/urandom)。
该函数用法与 insert-file-contents 一致,区别在于逐字节处理文件内容,必要时直接转换为 8 位字符。它不会运行 after-insert-file-functions,不执行格式解码、字符编码转换、自动解压等操作。
若需将文件名传递给其他进程供外部程序读取,可使用函数 file-local-copy,参见 实现“魔法”文件名机制。