だから私は(非常に大きな、〜155 + MB)バイナリファイルから読み取り、仕様に従ってそれを解析し、必要な情報を(CSV、フラットテキストに)書き出すアルゴリズムを持っています。出力の最初の 1,550 万行は問題なく動作し、約 0.99 ~ 1.03 GB の CSV ファイルが生成されます。これは、バイナリ ファイルの 20% 以上をほとんど通過しません。この後、突然印刷されたデータがバイナリファイルに表示されているものとまったく異なるため、壊れます。バイナリ ファイルを確認しましたが、同じパターンが続きます (データは「パケット」に分割されます - 以下のコードを参照してください)。処理方法により、メモリの使用量が実際に増加することはありません (安定して ~15K)。機能コードを以下に示します。それは私のアルゴリズムですか (もしそうなら、なぜ 1,550 万行で壊れるのですか?!)...ファイル サイズが大きいために考慮していない他の影響はありますか? 何か案は?
(fyi: 各「パケット」の長さは 77 バイトで、3 バイトの「開始コード」で始まり、5 バイトの「終了コード」で終わります。以下のパターンが表示されます)
編集コードは、以下の提案に基づいて更新されました...ありがとう!
private void readBin(string theFile)
{
List<int> il = new List<int>();
bool readyForProcessing = false;
byte[] packet = new byte[77];
try
{
FileStream fs_bin = new FileStream(theFile, FileMode.Open);
BinaryReader br = new BinaryReader(fs_bin);
while (br.BaseStream.Position < br.BaseStream.Length && working)
{
// Find the first startcode
while (!readyForProcessing)
{
// If last byte of endcode adjacent to first byte of startcod...
// This never occurs outside of ending/starting so it's safe
if (br.ReadByte() == 0x0a && br.PeekChar() == (char)0x16)
readyForProcessing = true;
}
// Read a full packet of 77 bytes
br.Read(packet, 0, packet.Length);
// Unnecessary I guess now, but ensures packet begins
// with startcode and ends with endcode
if (packet.Take(3).SequenceEqual(STARTCODE) &&
packet.Skip(packet.Length - ENDCODE.Length).SequenceEqual(ENDCODE))
{
il.Add(BitConverter.ToUInt16(packet, 3)); //il.ElementAt(0) == 2byte id
il.Add(BitConverter.ToUInt16(packet, 5)); //il.ElementAt(1) == 2byte semistable
il.Add(packet[7]); //il.ElementAt(2) == 1byte constant
for(int i = 8; i < 72; i += 2) //start at 8th byte, get 64 bytes
il.Add(BitConverter.ToUInt16(packet, i));
for (int i = 3; i < 35; i++)
{
sw.WriteLine(il.ElementAt(0) + "," + il.ElementAt(1) +
"," + il.ElementAt(2) + "," + il.ElementAt(i));
}
il.Clear();
}
else
{
// Handle "bad" packets
}
} // while
fs_bin.Flush();
br.Close();
fs_bin.Close();
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}