2016-08-11 7 views
2

이전 Delphi 앱을 C#으로 변환하려고합니다. 그것은 아래에 두었던 packed records을 통해 작성된 binary files으로 몇 가지 작업을 수행합니다. 그러나 BInfoRecrecord만이 파일에 있고 처음 나타나는 것으로 보장됩니다. 다른 것들은 그 안에있을 수도 있고 가지지 않을 수도 있으며 그 순서는 알 수 없습니다. 특히 한 가지 방법으로 문제가 있습니다. FileStream.Read을 통해 읽은 바이트 수를 가져오고 그 중 하나를 packed records 중 하나로 읽습니다. 그런 다음 첫 번째 if 문 (델파이 버전)에서 힙에 메모리를 할당하고 이전과 동일한 작업을 수행하지만 포인터로 읽습니다. 이 문제를 해결하는 가장 좋은 방법을 찾으려고 노력하고 있지만 델파이의 전문가는 아닙니다.델파이 포인터와 스트림을 C로 변환 #

델파이 코드 :

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) 편리하지는 않습니다.

그래, 내가 당신이라면 나는 바이트 배열을 할당하고 그 내용을 읽어 들일 것이다.