1

TFilestream を使用してファイルの内容を取得しようとしています。

procedure ShowFileCont(myfile : string);
var
tr : string;
fs : TFileStream;
Begin
   Fs   := TFileStream.Create(myfile, fmOpenRead or fmShareDenyNone); 
   SetLength(tr, Fs.Size);
   Fs.Read(tr[1], Fs.Size);
   Showmessage(tr); 
   Fs.Free;
end;

コンテンツのみの小さなテキスト ファイルを作成します。

  1. このファイルを (AkelPad を使用して) 1251 (ansi) codepege で保存します。
  2. 65001 (UTF8) コードページで保存します。

これらのファイルのサイズは異なりますが、内容は同じです-両方をメモ帳で開いたところ、両方とも同じ内容です

しかし、ShowFileCont proc を実行すると、異なる結果が表示されます。

  1. aaaaaaaJ?ЊT?8?V?"?A?aaaaaaa
  2. aaaaaaaJ“њРЉTщЂ®8ЈЏVд”Ј¦AИaaaaaaa

質問:

  1. TFilestream を使用して実際のファイルの内容を取得する方法は?
  2. これら 2 つのファイルのサイズは異なりますが、内容 (メモ帳) は同じであることをどのように説明できますか?

追加: 申し訳ありませんが、Lazarus FPC と string = utf8string を使用しているとは言いませんでした

4

2 に答える 2

3

ファイルのサイズが異なるのはなぜですか?

それらは異なるエンコーディングを使用するためです。1251 エンコーディングは、各文字を 1 バイトにマップします。ただし、UTF-8 では、各文字の可変バイト数が使用されます。

実際のファイルの内容を取得するにはどうすればよいですか?

ファイルで使用されているエンコーディングと一致する文字列型を使用する必要があります。たとえば、コンテンツが UTF-8 でエンコードされている場合は、これが最適な選択であり、コンテンツを UTF-8 文字列にロードします。stringUTF-8 でエンコードされたモードで FPC を使用しています。その場合、問題のコードが必要なものです。

たとえば、コード ページが 1251 の MBCS でエンコードされたファイルを読み込むのは、さらに注意が必要です。それを変数にロードすることができAnsiString、システムのロケールが 1251 である限り、変換は正しく実行されます。

ただし、ロケールが異なるマシンで実行すると、コードの動作が異なります。また、1252 などの異なる MBCS エンコーディングを使用してテキストをロードする場合、このアプローチは使用できません。バイト配列にロードしてから、たとえば 1252 から UTF-8 に変換して、その UTF-8 をstring変数に格納できるようにする必要があります。

LConvEncodingそのために、LCLのユニットを使用できます。たとえばCP1251ToUTF8CP1252ToUTF8などを使用して、MBCS から UTF-8 に変換できます。

どのエンコーディングが使用されているかをファイルから判断するにはどうすればよいですか?

それはいけません。多くの場合、正確な推測を行うことができます。しかし、一般に、テキストを表すバイト配列のエンコーディングを識別することはまったく不可能です。

ファイルを取得して、特定のエンコーディングを除外できる場合があります。たとえば、すべてのバイト ストリームが有効な UTF-8 または UTF-16 テキストであるとは限りません。したがって、そのようなファイルを除外できます。ただし、1251、1252 などのエンコーディングでは、任意のバイト ストリームが有効です。1251 のエンコードされたストリームと 1252 のエンコードされたストリームを 100% の精度で区別する方法はありません。

LConvEncodingユニットには、GuessEncoding何らかの用途があるように聞こえる音があります。

于 2013-05-21T15:26:23.860 に答える