2011-11-04 137 views
2

我想读\写它具有以下结构的二进制文件:读写结构化二进制文件

enter image description here

该文件由“记录”组成。每个 “RECORD” 具有以下结构: 我将使用第一记录如实施例

  • (红色)START字节:0x5A(始终为1字节,固定值0x5A)
  • (绿色)LENGTH字节:0×00 0x16(始终为2个字节,值可以从 “0x00 0x02”变为“0xFF 0xFF”)
  • (蓝色)内容:LENGTH字段减号2的十进制值指示的字节数。在这种情况下,LENGHT字段值为22(0x00 0x16转换为十进制),因此CONTENT将包含20(22 - 2)个字节。

我的目标是逐条读取每条记录,并将其写入输出文件。 其实我有读取功能和写入功能(伪代码):

private void Read(BinaryReader binaryReader, BinaryWriter binaryWriter) 
{ 
    byte START = 0x5A; 
    int decimalLenght = 0; 
    byte[] content = null; 
    byte[] length = new byte[2]; 

    while (binaryReader.PeekChar() != -1) 
    { 
     //Check the first byte which should be equals to 0x5A 
     if (binaryReader.ReadByte() != START) 
     { 
      throw new Exception("0x5A Expected"); 
     } 

     //Extract the length field value 
     length = binaryReader.ReadBytes(2); 

     //Convert the length field to decimal 
     int decimalLenght = GetLength(length); 

     //Extract the content field value 
     content = binaryReader.ReadBytes(decimalLenght - 2); 

     //DO WORK 
     //modifying the content 

     //Writing the record 
     Write(binaryWriter, content, length, START); 
    } 
} 

private void Write(BinaryWriter binaryWriter, byte[] content, byte[] length, byte START) 
{ 
    binaryWriter.Write(START); 
    binaryWriter.Write(length); 
    binaryWriter.Write(content); 
} 

这种方式实际上是工作。 但是,由于我处理的文件非常大,我发现它根本没有执行,导致我读写3次记录。其实我想读取数据的错误块,而不是少量的字节,也许在内存中工作,但我使用Stream的经验停止与BinaryReader和BinaryWriter。提前致谢。

回答

2

FileStream已经被缓冲,所以我想预计它工作得很好。如果你真的需要,你总是可以在原始流的周围创建一个BufferedStream以增加额外的缓冲,但是我怀疑它会产生显着的差异。

你说这是“没有表现” - 多快它工作?你有多确定IO是你的时间?你有没有执行任何代码分析?

+0

FileStream具有控制缓冲区大小的构造函数参数。另一件要考虑的事是操作系统本身也有缓冲。 –

+0

@JamesJohnston:确实。我希望大多数情况下的默认值都可以。我怀疑这确实是个问题。 –

+0

我同意。虽然我遇到了一个例外情况,尽管没有使用C#。我使用的C运行时默认为一个512字节的缓冲区。因此,当一次读取数据文件4个字节时(我们的程序所做的),磁盘性能会非常慢。当然,这通常不是问题,因为即使程序没有做足够的工作,操作系统也会缓冲读取。 –

1

我可能还建议您最初读取3(或6?)个字节,而不是2个单独的读取。将最初的字节放在一个小数组中,检查5a ck字节,然后检查2字节长度指示符,然后3字节AFP操作码THEN读取AFP记录的其余部分。

这是一个小的差异,但它摆脱了你的一个阅读电话。

我不是乔恩斯基特,但我在全国最大的印刷&邮件商店相当长的一段人做的工作,我们也大多AFP输出:-)

(通常是C,虽然)