读取D中的文本文件
是否有任何一刀切(或多或少)的方法来读取D中的文本文件 要求函数自动检测编码并以一致的格式提供文件的全部数据,如读取D中的文本文件,d,phobos,D,Phobos,是否有任何一刀切(或多或少)的方法来读取D中的文本文件 要求函数自动检测编码并以一致的格式提供文件的全部数据,如字符串或数据字符串。它应该自动检测BOM,并根据需要对其进行解释 我尝试了std.file.readText(),但它不能很好地处理不同的编码 (当然,这将有一个非零的故障率,这对我的应用程序来说是可以接受的。)我认为,在这一点上,Phobos中文件I/O的唯一实际选项(除了调用C函数)是std.file.readText和std.stdio.filereadText将以字符、wcha
字符串
或数据字符串
。它应该自动检测BOM,并根据需要对其进行解释
我尝试了std.file.readText()
,但它不能很好地处理不同的编码
(当然,这将有一个非零的故障率,这对我的应用程序来说是可以接受的。)我认为,在这一点上,Phobos中文件I/O的唯一实际选项(除了调用C函数)是
std.file.readText
和std.stdio.file
readText
将以字符、wchars或dchars数组的形式读取文件(默认为不可变(char)[]-即字符串)。我认为chars、wchars和dchars的编码必须分别为UTF-8、UTF-16和UTF-32,尽管我必须深入研究源代码才能确定。任何与这些编码兼容的编码(例如,ASCII与UTF-8兼容)都可以正常工作
如果使用文件
,则可以使用多个函数选项读取文件-包括readln
和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表留给读者作为练习。Hm。。。知道如何处理BOM吗?@Lambert,我强烈建议使用read(),因为它不会进行任何验证,但您可以自己执行,并且不会多次读取文件。对于BOM表,您可以强制转换为ubyte并比较第一个字节,然后对切片的其余部分执行强制转换…嗯。。。这不是我希望的解决方案(我不想手动检查BOM),但我想这也不算太糟;谢谢。@Lambert:检查BOM应该不会太糟糕。IIRC它只有32位(或更少),只有大约六个值(包括大/小结束)。@BCS:o__oBOM是32位吗?UTF-8的
0xEF、0xBB、0xBF
呢?