C# 二进制文件使用C读取预定义的字节数/字节#
场景 我有一个二进制文件,它是某个系统的输出。供应商向我们提供了文件编码的说明。它非常复杂,因为编码遵循某种方法。例如,第一个字节是ISO编码的,我们需要首先对其进行解码,如果该值与提供的列表匹配,则它具有某种意义。接下来的15个字节也是ISO编码的,我们需要对其进行解码和比较。类似地,在某些位置之后,很少有字节是二进制编码的。。诸如此类 迄今为止的行动 我将使用C#WinForm应用程序。到目前为止,我已经查看了各种文档,它们都指向FileStream/BinaryReader的组合,因为我的文件大小在1G到1.8G之间。我也不能将整个文件放在一个字节[]中 问题C# 二进制文件使用C读取预定义的字节数/字节#,c#,character-encoding,binaryfiles,C#,Character Encoding,Binaryfiles,场景 我有一个二进制文件,它是某个系统的输出。供应商向我们提供了文件编码的说明。它非常复杂,因为编码遵循某种方法。例如,第一个字节是ISO编码的,我们需要首先对其进行解码,如果该值与提供的列表匹配,则它具有某种意义。接下来的15个字节也是ISO编码的,我们需要对其进行解码和比较。类似地,在某些位置之后,很少有字节是二进制编码的。。诸如此类 迄今为止的行动 我将使用C#WinForm应用程序。到目前为止,我已经查看了各种文档,它们都指向FileStream/BinaryReader的组合,因为我的
我面临着逐字节读取文件的问题。根据上面的场景,首先我只需要读取1个字节,然后是15个字节,然后是10个字节,依此类推。如何做到这一点。提前感谢你的帮助 BinaryReader.ReadBytes方法
将当前流中指定数量的字节读取到字节数组中,并将当前位置前进该数量的字节
BinaryReader是一个不错的选择,因为它使用的是流,所以内存使用率很低。 现在,您可以执行以下操作:
internal struct MyHeader
{
public byte FirstByte;
// etc
}
internal class MyFormat
{
private readonly string _fileName;
private MyFormat(string fileName)
{
_fileName = fileName;
}
public MyHeader Header { get; private set; }
public string FileName
{
get { return _fileName; }
}
public static MyFormat FromFileName(string fileName)
{
if (fileName == null) throw new ArgumentNullException("fileName");
// read the header of your file
var header = new MyHeader();
using (var reader = new BinaryReader(File.OpenRead(fileName)))
{
byte b1 = reader.ReadByte();
if (b1 != 0xAA)
{
// return null or throw an exception
}
header.FirstByte = b1;
// you can also read block of bytes with a BinaryReader
var readBytes = reader.ReadBytes(10);
// etc ... whenever something's wrong return null or throw an exception
}
// when you're done reading your header create and return the object
var myFormat = new MyFormat(fileName);
myFormat.Header = header;
// the rest of the object is delivered only when needed, see method below
return myFormat;
}
public object GetBigContent()
{
var content = new object();
// use FileName and Header property to get your big content and return it
// again, use a BinaryReader with 'using' statement here
return content;
}
}
解释
调用MyFormat.FromFileName
在其中创建以下对象之一:
- 每当发生错误时,您都会分析标头,并返回null或引发异常
- 一旦你的头被解析,你就创建了这个对象并返回它,就这样了
GetBigContent
或任何您想调用的名称
在该方法中使用标题
和文件名
,您将获得按需从该文件返回内容所需的一切
通过这种方式,
- 您只需解析一个有效对象的头,就可以快速返回该对象
- 您在第一次呼叫时不会消耗1.8Gb
- 您只按需返回用户需要的内容
encoding
类可能会对您有所帮助:
Stream和BinaryReader都有读取单个字节和读取多个字节的方法(Stream:ReadByte/Read,BinaryReader:ReadByte/ReadBytes)——它们都不要求您将整个文件读入一个字节[]。OP可能知道,他正在寻找一种解决问题的通用方法。“我只需要读取1个字节,然后是15个字节,然后是10个字节,依此类推。我想如果我的答案太长的话,他也不能把整个1.8Gb的文件放在一个数组中。
internal struct MyHeader
{
public byte FirstByte;
// etc
}
internal class MyFormat
{
private readonly string _fileName;
private MyFormat(string fileName)
{
_fileName = fileName;
}
public MyHeader Header { get; private set; }
public string FileName
{
get { return _fileName; }
}
public static MyFormat FromFileName(string fileName)
{
if (fileName == null) throw new ArgumentNullException("fileName");
// read the header of your file
var header = new MyHeader();
using (var reader = new BinaryReader(File.OpenRead(fileName)))
{
byte b1 = reader.ReadByte();
if (b1 != 0xAA)
{
// return null or throw an exception
}
header.FirstByte = b1;
// you can also read block of bytes with a BinaryReader
var readBytes = reader.ReadBytes(10);
// etc ... whenever something's wrong return null or throw an exception
}
// when you're done reading your header create and return the object
var myFormat = new MyFormat(fileName);
myFormat.Header = header;
// the rest of the object is delivered only when needed, see method below
return myFormat;
}
public object GetBigContent()
{
var content = new object();
// use FileName and Header property to get your big content and return it
// again, use a BinaryReader with 'using' statement here
return content;
}
}