8

Dのテキストファイルを読むための万能の(多かれ少なかれ)方法はありますか?

要件は、関数がエンコーディングを自動検出し、ファイルのデータ全体をastringや。などの一貫した形式で提供することdstringです。BOMを自動検出し、適切に解釈する必要があります。

試しstd.file.readText()ましたが、異なるエンコーディングをうまく処理できません。

(もちろん、これはゼロ以外の失敗率になります、そしてそれは私のアプリケーションにとって許容できます。)

4

2 に答える 2

8

現時点で(C関数の呼び出しを除いて)PhobosでのファイルI / Oの実際のオプションは、とだけだと思いstd.file.readTextますstd.stdio.FilereadTextchars、wchars、またはdcharsの配列としてファイルを読み込みます(デフォルトはimmutable(char)[]-つまり文字列)。確実にソースコードを掘り下げる必要がありますが、chars、wchars、およびdcharsのエンコーディングはそれぞれUTF-8、UTF-16、およびUTF-32である必要があると思います。それらのエンコーディングと互換性のあるエンコーディング(たとえば、ASCIIはUTF-8と互換性があります)は問題なく動作するはずです。

を使用する場合は、-includeおよび。Fileを使用してファイルを読み取る関数にいくつかのオプションがあります。ただし、基本的には、と同じようにUTF-8、UTF-16、またはUTF-32互換のエンコーディングを使用してファイルを読み取るか、バイナリデータとして読み込んで自分で操作します。readlnrawReadreadText

Dの文字タイプはchar、wchar、およびdcharであり、それぞれUTF-8、UTF-16、およびUTF-32コード単位であるため、データをバイナリ形式で読み取りたい場合を除き、ファイルには次のようになります。これらの3つのタイプのユニコードのいずれかと互換性のあるエンコーディングでエンコードされます。特定のエンコーディングの文字列を指定すると、の関数を使用して別のエンコーディングに変換できますstd.utfreadTextただし、特定のエンコーディングでファイルを読み取って成功するかどうかを確認する以外に、ファイルのエンコーディングタイプをクエリする方法を知りません。

readTextしたがって、ファイルを自分で処理して、そのファイルがどのエンコーディングであるかをその場で判断したい場合を除いて、おそらく、成功する最初の文字列を使用して、連続する各文字列タイプで使用するのが最善の策です。ただし、テキストファイルは通常UTF-8またはUTF-8互換のエンコーディングであるreadTextため、通常の文字列で使用すると、ほとんどの場合問題なく機能すると思います。

于 2011-01-18T00:04:05.583 に答える
4

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を追加することは、読者の演習として残されています。

于 2011-01-19T15:48:11.987 に答える