Sli*_*lim 2 .net c# large-files
所以我有一个从(非常大的,~155 + MB)二进制文件读取的算法,根据规范解析它并写出必要的信息(到CSV,平面文本).对于前1550万行输出,它可以完美地工作,产生约0.99-1.03 GB的CSV文件.这几乎超过了二进制文件的20%.在此之后它会中断,因为突然打印的数据根本不是二进制文件中显示的内容.我检查了二进制文件,相同的模式继续(数据分成"数据包" - 见下面的代码).由于它的处理方式,内存使用量从未真正增加(稳定~15K).功能代码如下所示.这是我的算法(如果是这样,为什么它会在1550万行之后中断?!)......是否还有其他影响因为大文件大小我没有考虑?有任何想法吗?
(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());
}
}Run Code Online (Sandbox Code Playgroud)
LBu*_*kin 17
您的代码正在静默捕获while循环中发生的任何异常并吞下它.
这是一种不好的做法,因为它掩盖了您遇到的问题.
最有可能的是,你在循环中调用的方法之一(int.Parse()例如)抛出一个异常,因为它遇到了数据格式的某些问题(或者你对该格式的假设).
一旦发生异常,读取数据的循环就会被抛弃,因为它不再位于记录边界.
您应该做几件事来使这段代码更具弹性:
| 归档时间: |
|
| 查看次数: |
4026 次 |
| 最近记录: |