在D中读取文本文件

时间:2011-01-17 21:14:41

标签: d phobos

在D中读取文本文件是否有任何一刀切(或多或少)的方法?

要求是该功能会自动检测编码并以一致的格式提供文件的整个数据,例如stringdstring。它应该自动检测BOM并在适当时解释它们。

我尝试了std.file.readText(),但它不能很好地处理不同的编码。

(当然,这将是一个非零失败率,这对我的应用程序来说是可以接受的。)

2 个答案:

答案 0 :(得分:8)

我认为此时Phobos中文件I / O的唯一真正选项(除了调用C函数之外)是std.file.readTextstd.stdio.FilereadText将在文件中读取字符,wchars或dchars数组(默认为immutable(char)[] - 即字符串)。我认为编码对于字符,wchars和dchars分别必须是UTF-8,UTF-16和UTF-32,尽管我必须深入挖掘源代码才能确定。任何与这些编码兼容的编码(例如ASCII与UTF-8兼容)应该可以正常工作。

如果您使用File,那么您可以使用多种选项来读取文件 - 包括readlnrawRead。但是,您基本上使用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几乎总能正常工作。

答案 1 :(得分:4)

至于处理检查物料清单:

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是留给读者的练习。