4

C#でバイナリファイルにテキストを書き込んでいますが、文字列と文字配列の書き込みの量に違いがあります。System.IO.BinaryWriterを使用しており、書き込みが発生するときにBinaryWriter.BaseStream.Lengthを監視しています。これらは私の結果です:

using(BinaryWriter bw = new BinaryWriter(File.Open(“data.dat”), Encoding.ASCII))
{
  string value = “Foo”;

  // Writes 4 bytes
  bw.Write(value);

  // Writes 3 bytes 
  bw.Write(value.ToCharArray());
}

ASCII文字を3つしか書き込んでいないのに、文字列のオーバーロードが4バイトを書き込む理由がわかりません。誰かがこれを説明できますか?

4

4 に答える 4

13

のドキュメントにBinaryWriter.Write(string)は、このストリームに長さのプレフィックスが付いた文字列が書き込まれると記載されています。のオーバーロードにWrite(char[])は、そのようなプレフィックスはありません。

余分なデータは長さであるように私には思えます。

編集:

もう少し明確にするために、Reflectorを使用してください。Write(string)メソッドの一部として、次のコードが含まれていることがわかります。

this.Write7BitEncodedInt(byteCount);

これは、可能な限り少ないバイト数を使用して整数をエンコードする方法です。短い文字列(128文字未満の文字列を日常的に使用する)の場合、1バイトを使用して表すことができます。より長い文字列の場合、より多くのバイトを使用し始めます。

興味がある場合に備えて、その関数のコードを次に示します。

protected void Write7BitEncodedInt(int value)
{
    uint num = (uint) value;
    while (num >= 0x80)
    {
        this.Write((byte) (num | 0x80));
        num = num >> 7;
    }
    this.Write((byte) num);
}

このエンコーディングを使用して長さのプレフィックスを付けた後、目的のエンコーディングで文字のバイトを書き込みます。

于 2009-06-18T19:40:56.787 に答える
5

BinaryWriter.Write(string) ドキュメントから:

BinaryWriterの現在のエンコーディングで、長さのプレフィックスが付いた文字列をこのストリームに書き込み、使用されているエンコーディングとストリームに書き込まれている特定の文字に従って、ストリームの現在の位置を進めます。

この動作はおそらくBinaryReader、文字列を使用してファイルを読み戻すときに識別できるようにするためです。(たとえば3Foo3Bar6Foobar、文字列「Foo」、「Bar」、「Foobar」に解析できますが、解析FooBarFoobarできませんでした。)実際、BinaryReader.ReadStringこの情報を正確に使用しstringて、バイナリファイルからを読み取ります。

BinaryWriter.Write(char[]) ドキュメントから:

文字配列を現在のストリームに書き込み、使用されているエンコーディングとストリームに書き込まれている特定の文字に従って、ストリームの現在の位置を進めます。

MSDNのドキュメントがどれほど包括的で有用であるかを誇張するのは難しいです。常に最初に確認してください。

于 2009-06-18T19:42:59.213 に答える
1

すでに述べたように、BinaryWriter.Write(String)は、文字列自体を書き込む前に、文字列の長さをストリームに書き込みます。

これにより、BinaryReader.ReadString()は文字列の長さを知ることができます。

using (BinaryReader br = new BinaryReader(File.OpenRead("data.dat")))
{
    string foo1 = br.ReadString();
    char[] foo2 = br.ReadChars(3);
}
于 2009-06-18T19:54:29.317 に答える
0

実際に書かれたものを見ましたか?ヌルターミネータだと思います。

于 2009-06-18T19:33:09.483 に答える