2016-08-11 5 views
2

私は古いDelphiアプリをC#に変換しようとしています。それは私が下に置いたpacked recordsを介して書かれたbinary filesでいくつかのものを行います。ただし、BInfoRecrecordのみがファイルに存在し、最初に表示されることが保証されています。他の人はそこにいてもいなくてもよく、その順序は不明です。私は特に一つの方法に問題があります。読み込み中のバイト数はFileStream.Readで、それをpacked recordsのいずれかに読み込んでいます。次に、最初のifステートメント(delphiバージョン)では、ヒープ上にメモリを割り当てています。以前と同じことをやっていますが、ポインタに読み込んでいます。私はこれについて最善の方法を理解しようとしていますが、私は決してデルファイの専門家ではありません。Delphiのポインタとストリームを変換する.C#

Delphiコード:

StartP = packed record 
    x:SmallInt; 
    y:SmallInt; 
end; 

InfoP = packed record 
Ycoord:double;  
Xcoord:double;    
//other vars here 
end; 

HeadP = packed record 
    NumP:DWORD; 
    SizeStruct:DWORD; 
    SizePoStruct:DWORD; 
    //other vars here 
end; 

BInfoRec = packed record 
    StructNum : WORD ; 
    in_size : WORD ;  
    //other variables here 
end; 

var 
    tStream:TFileStream; 
    bInfo:BInfoRec; 
    RestOfBFile:Pointer; 
    sizeofRest:Integer; 

Function LoadBFile(FileName:String):Boolean; 
var 
    sizeread:Integer; 
begin 
    Try 
    LoadBFile:=False; 
    tStream:=TFileStream.Create(Filename,fmOpenRead); 
    sizeofRest:=tStream.Size-Sizeof(bInfo); 
    sizeread:=tStream.Read(bInfo,Sizeof(bInfo)); 
    if sizeread = Sizeof(bInfo) then 
    begin           //best way to convert this? 
      RestOfBFile:=AllocMem(sizeofRest); 
      sizeread:=tStream.Read(RestOfBFile^,sizeofRest); 
      if SizeofRest= SizeRead then 
      LoadBFile:=True; 
    end; 
    tStream.Free; 
    except 
     LoadBFile:=False; 
     tStream.Free; 
    end; 
end; 

のC#(私がこれまで持っているもの):

[Serializable()] 
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 
public struct StartP 
{ 
    public short x; 
    public short y; 
} 

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 
public struct InfoP 
{ 
    public double Ycoord; 
    public double Xcoord; 
    //other vars here 
} 

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 
public struct HeadP 
{ 
    public UInt32 NumP; 
    public UInt32 SizeStruct; 
    public UInt32 SizePoStruct; 
    //other vars here 
} 

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] 
public struct BInfoRec 
{ 
    public ushort StructNum; 
    public ushort in_size;   
} 

BInfoRec bInfo; 
int sizeOfRest; 

private Boolean LoadBFile(string fileName) 
{ 
    int sizeRead; 
    byte[] buffer = new byte[Marshal.SizeOf(bInfo)]; 

    try 
    { 
     using (var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None)) 
     { 
      sizeOfRest = (int)stream.Length - Marshal.SizeOf(typeof(BInfoRec)); 
      sizeRead = stream.Read(buffer, 0, Marshal.SizeOf(typeof(BInfoRec))); 
      if (sizeRead == Marshal.SizeOf(typeof(BInfoRec))) 
      { 
       //what goes here?? 

       if (sizeOfRest == sizeRead) 
       { 
        return true; 
       } 
      } 
     } 
    } 
    catch (Exception ex) 
    { 
     return false; 
    } 
} 

私は未知のサイズの新しいバイト配列を作成し、中に読み取ることがBinaryReaderを使用して考えていました残りのファイルをその配列に追加し、そのサイズを確認するだけです。それが最良の方法であるかどうかは分かりませんか?

答えて

1

これは任意のサイズのメモリブロックです。バイト配列以外のオプションがたくさんあるとは思わない。はい、管理されていないメモリ(たとえばMarshal.AllocHGlobal)を割り当てることはできますが、それはほとんど便利ではありません。

私があなただったら、バイト配列を割り当て、その内容を読み込みます。

関連する問題