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中认为的更难:)
谢谢!
假设这是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)
如果你坚持使用结构,你应该使你的结构不可变,并为每个字段创建一个带有参数的构造函数.
如果您可以使用不安全的代码:
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)
这种不安全的方式几乎是即时的,速度更快,尤其是当你一次转换很多结构时.问题是你想使用不安全的.如果你绝对需要性能提升,我的建议只使用不安全的方法.