有没有一种千篇一律(或多或少)的方式来读取 D 中的文本文件?
要求是该函数将自动检测编码并以一致的格式为我提供文件的整个数据,例如 astring
或 a dstring
。它应该自动检测 BOM 并根据需要对其进行解释。
我试过std.file.readText()
了,但它不能很好地处理不同的编码。
(当然,这将有一个非零故障率,这对我的应用程序来说是可以接受的。)
我相信目前在 Phobos 中文件 I/O 的唯一真正选择(除了调用 C 函数)是std.file.readText
和std.stdio.File
. readText
将在文件中读取为 chars、wchars 或 dchars 数组(默认为 immutable(char)[] - 即字符串)。我认为 chars、wchars 和 dchars 的编码必须分别为 UTF-8、UTF-16 和 UTF-32,尽管我必须深入研究源代码才能确定。任何与这些编码兼容的编码(例如 ASCII 与 UTF-8 兼容)都应该可以正常工作。
如果您使用File
,那么您有几个函数选项可以使用 -includereadln
和来读取文件rawRead
。但是,您基本上使用 UTF-8、UTF-16 或 UTF-32 兼容编码读取文件,就像使用 一样readText
,或者您将其作为二进制数据读取并自己操作。
由于 D 中的字符类型是 char、wchar 和 dchar,它们分别是 UTF-8、UTF-16 和 UTF-32 代码单元,除非你想以二进制格式读取数据,否则文件将有以与这三种 unicode 之一兼容的编码进行编码。给定一个特定编码的字符串,您可以使用 中的函数将其转换为另一种编码std.utf
。readText
但是,除了使用给定编码尝试读取文件并查看它是否成功之外,我不知道有任何方法可以查询文件的编码类型。
因此,除非您想自己处理文件并动态确定它的编码,否则最好的选择可能是只使用readText
每个连续的字符串类型,使用第一个成功的字符串。但是,由于文本文件通常采用 UTF-8 或 UTF-8 兼容编码,我希望readText
与普通字符串一起使用几乎总是可以正常工作。
至于处理检查BOM:
char[] ConvertViaBOM(ubyte[] data) {
char[] UTF8() { /*...*/ }
char[] UTF16LE(){ /*...*/ }
char[] UTF16BE(){ /*...*/ }
char[] UTF32LE(){ /*...*/ }
char[] UTF32BE(){ /*...*/ }
switch (data.length) {
default:
case 4:
if (data[0..4] == [cast(ubyte)0x00, 0x00, 0xFE, 0xFF]) return UTF32BE();
if (data[0..4] == [cast(ubyte)0xFF, 0xFE, 0x00, 0x00]) return UTF32LE();
goto case 3;
case 3:
if (data[0..3] == [cast(ubyte)0xEF, 0xBB, 0xBF]) return UTF8();
goto case 2;
case 2:
if (data[0..2] == [cast(ubyte)0xFE, 0xFF]) return UTF16BE();
if (data[0..2] == [cast(ubyte)0xFF, 0xFE]) return UTF16LE();
goto case 1;
case 1:
return UTF8();
}
}
添加更多模糊的 BOM 留给读者作为练习。