-2

BinaryWriter を使用してデータをログ ファイルに書き込みます。

ただし、BinaryReader を使用して (ループ内で) データを取得すると、最初の 3 つの書き込み (integer、integer、byte[]) を読み取ることができますが、別の 3 つを読み取るためのループ内の次の反復では、残りのデータ(そして私はそれを処理できません)。

コードは次のとおりです。

コードを書く:

writer.Write(header.StructID);
writer.Write(data.Length);
writer.Write(data);

コードを読む:

using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
    using (BinaryReader br = new BinaryReader(fs))
    {
        long bytesRead = 0;
        long readerLen = br.BaseStream.Length;

        //read 1st record
        int id = br.ReadInt32();
        int len = br.ReadInt32();
        byte[] data = br.ReadBytes(len);
        bytesRead += (sizeof(int) * 2) + data.Length;

        while (bytesRead < readerLen)
        {
            //TODO:process data

            //read next
            id = br.ReadInt32();
            len = br.ReadInt32();
            data = br.ReadBytes(len);
            bytesRead += (sizeof(int) * 2) + data.Length;
        }
    }
}

解決にご協力をお願いいたします。

編集:

バイナリ書き込みコードを using ステートメントで囲み、1 回だけ実行できるようにしたので、書き込まれたバイト数が正確にわかります。読み取りコードを処理すると、basestream.length がかなり大きくなります (つまり、80 バイトを書き込み、basestream.length は 1144 を示します)。

    using (writer = new BinaryWriter(File.Open(filename, FileMode.OpenOrCreate)))
            {
                long pos = writer.BaseStream.Position;
                writer.Write(header.StructID);
                writer.Write(data.Length);
                writer.Write(data);
                m_LoggingEnabled = false;
            }

バイナリデータは次のとおりです。

CE 00 00 00 48 00 00 00 AD A2 3B 94 76 08 A7 3E 7A 9A 80 9D CC 1A 2B 3F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0 BF 91 01 00 00 00 00 00 00 00 00 00 00 00 00 F0 3F 01 00 00 00 00 00 00 00 CE 00 00 00 48 00 00 00 AD A2 3B 94 76 08 A7 3E 7A 9A 80 9D CC 1A 2B 3F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0 BF 92 01 00 00 00 00 00 00 00 00 00 00 00 2A 7A BE 01 00 00 00 50 64 63 3D CE 00 00 00 48 00 00 00 D8 41 B1 19 01 A3 86 BE E2 E2 7A 22 6F 1F 2B 3F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0 BF 91 01 00 00 00 00 00 00 00 00 00 00 00 00 F0 3F 01 00 00 00 00 00 00 00

私は今本当に混乱しています!

4

1 に答える 1

1

コードをリファクタリングBinaryReaderして反復を減らし、より簡潔にすることはできますが、コードは正しいです。

あなたの限られた説明に基づいて、あなたは読み方ではなく、書き方が間違っていると思います。header.StructIDdata.Lengthが整数型であることを確認してください。

Writeタイマーから BinaryReader を呼び出しているため、書き込みストリームを正しい位置に進めていないため、操作が既存のファイルの先頭から書き込まれることに注意する必要があります。これにより、望ましくない動作 (既存のデータの上書きなど) が発生する可能性があり、おそらく読み取りの問題が発生している可能性があります。Appendそれを防ぐには、モードでファイルを開く必要があります。

あなたの例に基づいて BinaryReader と BinaryWriter を使用して読み書きする正しい例を次に示します。ファイルでAppendModeを使用して、表示されている問題を防ぎます(forループでファイルを再度開いて、タイマーがファイルを再度開いて何かを書き込むことをシミュレートしています):

var stuffToWrite = new List<byte[]>()
{
    new byte[72],
        new byte[72],
        new byte[72],
};

for (int i = 0; i < stuffToWrite.Count; i++)
{

    using (var file = File.Open(filename, FileMode.Append))
    using (var binaryWriter = new BinaryWriter(file))
    {
        binaryWriter.Write(206);
        binaryWriter.Write((stuffToWrite[i].Length));
        binaryWriter.Write(stuffToWrite[i]);
    }
}

using (var fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var br = new BinaryReader(fs))
{
    do
    {
        int id = br.ReadInt32();
        int len = br.ReadInt32();
        byte[] data = br.ReadBytes(len);

        // Process Data

    } while (br.BaseStream.Position < br.BaseStream.Length);
}
于 2014-10-24T17:03:33.130 に答える