C#内存映射大文件并使用Marshal解析结构体信息
程序员文章站
2022-04-04 15:04:55
内存映射数据处理类主要函数及变量如下: 科学数据结构体定义如下: 图像数据结构体如下: ......
内存映射数据处理类主要函数及变量如下:
1 string _filepath; 2 /// <summary> 3 /// 引用内存映射文件 4 /// </summary> 5 private memorymappedfile _memoryfile = null; 6 /// <summary> 7 /// 用于访问内存映射文件的存取对象 8 /// </summary> 9 private memorymappedviewaccessor _accessor = null; 10 public scientificdata _scientificdata = new scientificdata(); 11 long _lenbyte = 0; 12 public datfileinfo(string filepath) 13 { 14 _filepath = filepath; 15 _memoryfile = memorymappedfile.createfromfile(_filepath); 16 _accessor = _memoryfile.createviewaccessor(); 17 // _stream = _memoryfile.createviewstream(); 18 fileinfo finfo = new fileinfo(filepath); 19 _lenbyte = finfo.length;//文件字节大小 20 } 21 public void saverawdata(string savepath) 22 { 23 24 int currentbytenum = 0;//当前字节位置 25 uint acountint = 0; 26 uint rcountint = 0; 27 scientificdata scientificdata = new scientificdata(); 28 byte[] data = new byte[1036 * 1036]; 29 while (currentbytenum<= (_lenbyte- 1036 * 1036)) 30 { 31 _accessor.read<uint>(currentbytenum, out rcountint); 32 _accessor.read<uint>(currentbytenum+4, out acountint); 33 if (rcountint < 1400 && acountint < 1401 && _accessor.readbyte(currentbytenum+8)==0x0a && _accessor.readbyte(currentbytenum + 9) == 0x0b)//初步判断条件,节省解析结构体时间 34 { 35 _accessor.readarray(currentbytenum, data, 0, data.length);//读取结构体数据到字节数组 36 scientificdata = bytetostructure<scientificdata>(data);//字节数组解析到结构体 37 if((scientificdata.aux_3a1 == 0x3a) && (scientificdata.aux_3a3 == 0x3a))//进一步判断 38 { 39 ushort[,] sdata = scientificdata.getimagedata();//得到所需的数据 40 saverawdata(savepath + ((int)((acountint - 1)/15+1)).tostring()+ "_" + (acountint-1).tostring() + "_"+acountint + "_"+scientificdata.aux_num + ".raw" , sdata); 41 currentbytenum += 1036 * 1036; 42 } 43 else 44 currentbytenum++; 45 } 46 else 47 currentbytenum++; 48 49 50 } 51 } 52 /// <summary> 53 /// 由byte数组转换为结构体 54 /// </summary> 55 public static t bytetostructure<t>(byte[] databuffer) 56 { 57 object structure = null; 58 int size = marshal.sizeof(typeof(t)); 59 intptr allocintptr = marshal.allochglobal(size); 60 try 61 { 62 marshal.copy(databuffer, 0, allocintptr, size); 63 structure = marshal.ptrtostructure(allocintptr, typeof(t)); 64 } 65 finally 66 { 67 marshal.freehglobal(allocintptr); 68 } 69 return (t)structure; 70 } 71 private void saverawdata(string savepath,ushort[,] data) 72 { 73 int len = data.length*2; 74 byte[] bdata = new byte[len]; 75 buffer.blockcopy(data,0,bdata,0,len); 76 file.writeallbytes(savepath, bdata); 77 } 78 /// <summary> 79 /// 由结构体转换为byte数组 80 /// </summary> 81 public static byte[] structuretobyte<t>(t structure) 82 { 83 int size = marshal.sizeof(typeof(t)); 84 byte[] buffer = new byte[size]; 85 intptr bufferintptr = marshal.allochglobal(size); 86 try 87 { 88 marshal.structuretoptr(structure, bufferintptr, true); 89 marshal.copy(bufferintptr, buffer, 0, size); 90 } 91 finally 92 { 93 marshal.freehglobal(bufferintptr); 94 } 95 return buffer; 96 }
科学数据结构体定义如下:
//一幅1036*1036字节数据定义 public struct scientificdata { /参数信息 [marshalas(unmanagedtype.byvalarray, sizeconst = 4)] public byte[] relativepacketcount; [marshalas(unmanagedtype.byvalarray, sizeconst = 4)] public byte[] absolutepacketcount; ........ public byte aux_3a;//填充3a h ......... [marshalas(unmanagedtype.byvalarray, sizeconst = 1036)] public oneimagerow[] imagedata;//图像数据行 /// <summary> /// 获取raw图数据 /// </summary> /// <returns>图像数据</returns> public ushort[,] getimagedata() { ushort[,] rawdata = new ushort[1036, 512]; for (int i = 0; i < 1036; i++) { var onerow = imagedata[i]; for (int j = 0; j < 512; j++) { rawdata[i, j] = (ushort)(((onerow.imagedata[j * 2] << 8) | onerow.imagedata[j * 2 + 1])) ; } } return rawdata; } }
图像数据结构体如下:
public struct oneimagerow { [marshalas(unmanagedtype.byvalarray, sizeconst = 4)] public byte[] relativepacketcount; [marshalas(unmanagedtype.byvalarray, sizeconst = 4)] public byte[] absolutepacketcount; [marshalas(unmanagedtype.byvalarray, sizeconst = 2)] public byte[] linehead;//行头 [marshalas(unmanagedtype.byvalarray, sizeconst = 2)] public byte[] linenum;//行号 [marshalas(unmanagedtype.byvalarray, sizeconst = 1024)] public byte[] imagedata;//图像数据512×2=1024字节 public static string bytetohex(byte[] bt) { var hex = bitconverter.tostring(bt, 0).toupper(); return hex; } }