記憶體對映資料處理類主要函式及變數如下:
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; } }