如何将字节块读入struct

Gab*_*tin 1 .net c# struct filestream

我有这个资源文件,我需要处理,包含一组文件.

首先,资源文件列出了其中包含的所有文件,以及其他一些数据,例如在此结构中:

struct FileEntry{
     byte Value1;
     char Filename[12];
     byte Value2;
     byte FileOffset[3];
     float whatever;
}
Run Code Online (Sandbox Code Playgroud)

所以我需要读取这个大小的块.

我正在使用FileStream中的Read函数,但是如何指定struct的大小?我用了:

int sizeToRead = Marshal.SizeOf(typeof(Header));
Run Code Online (Sandbox Code Playgroud)

然后将此值传递给Read,但之后我只能读取一组byte [],我不知道如何转换为指定的值(我知道如何获取单字节值...但不是其余的).

另外我需要指定一个不安全的上下文,我不知道它是否正确......

在我看来,读取字节流比我在.NET中认为的更难:)

谢谢!

Vas*_*sea 7

假设这是C#,我不会创建一个结构作为FileEntry类型.我会用字符串替换char [20]并使用BinaryReader - http://msdn.microsoft.com/en-us/library/system.io.binaryreader.aspx来读取单个字段.您必须按照写入的顺序读取数据.

就像是:

class FileEntry {
     byte Value1;
     char[] Filename;
     byte Value2;
     byte[] FileOffset;
     float whatever;
}

  using (var reader = new BinaryReader(File.OpenRead("path"))) {
     var entry = new FileEntry {
        Value1 = reader.ReadByte(),
        Filename = reader.ReadChars(12) // would replace this with string
        FileOffset = reader.ReadBytes(3),
        whatever = reader.ReadFloat()           
     };
  }
Run Code Online (Sandbox Code Playgroud)

如果你坚持使用结构,你应该使你的结构不可变,并为每个字段创建一个带有参数的构造函数.

 


Chr*_*ens 5

如果您可以使用不安全的代码:

unsafe struct FileEntry{
     byte Value1;
     fixed char Filename[12];
     byte Value2;
     fixed byte FileOffset[3];
     float whatever;
}

public unsafe FileEntry Get(byte[] src)
{
     fixed(byte* pb = &src[0])
     {
         return *(FileEntry*)pb;
     } 
}
Run Code Online (Sandbox Code Playgroud)

fixed关键字将数组嵌入struct中.由于它已修复,如果您经常创建这些问题并且从不让它们离开,这可能会导致GC问题.请记住,常量大小是n*sizeof(t).所以Filename [12]分配24个字节(每个char是2个字节的unicode),FileOffset [3]分配3个字节.如果您不处理磁盘上的unicode数据,这很重要.我建议将其更改为byte []并将结构转换为可用的类,您可以在其中转换字符串.

如果你不能使用不安全,你可以做整个BinaryReader方法:

public unsafe FileEntry Get(Stream src)
{
     FileEntry fe = new FileEntry();
     var br = new BinaryReader(src);
     fe.Value1 = br.ReadByte();
     ...
}
Run Code Online (Sandbox Code Playgroud)

这种不安全的方式几乎是即时的,速度更快,尤其是当你一次转换很多结构时.问题是你想使用不安全的.如果你绝对需要性能提升,我的建议只使用不安全的方法.