2010-12-13 67 views
0

我有以下內容的二進制文件:閱讀可變大小的字符串從二進制文件(VB6與C#)

alt text

下面的代碼是用來讀取舊VB6程序此內容:

Private Type tpClient 
    Firstname As String 
    LastName As String 
    Birth As String 
    Adres As String 
    Geslacht As String 
    IDNummer As Long 
    SSNummer As String 
    DatabaseID As Long 
    Telefoon1 As String 
    Telefoon2 As String 
End Type 

Open strFilePath For Random Access Read As #intFileNumber 
Get #intFileNumber, 1, ClientData ' ClientData is of type tpClient 

現在我想用我的新的C#程序讀取此:

[StructLayout(LayoutKind.Sequential, Pack = 1)] 
public struct PatientStruct 
{ 
    [MarshalAs(UnmanagedType.BStr)] 
    public string FirstName; 

    [MarshalAs(UnmanagedType.BStr)] 
    public string LastName; 

    [MarshalAs(UnmanagedType.BStr)] 
    public string BirthDate; 

    [MarshalAs(UnmanagedType.BStr)] 
    public string Address; 

    [MarshalAs(UnmanagedType.BStr)] 
    public string Gender; 

    [MarshalAs(UnmanagedType.BStr)] 
    public string IdNumber; 

    [MarshalAs(UnmanagedType.BStr)] 
    public string SsNumber; 

    [MarshalAs(UnmanagedType.BStr)] 
    public string DatabaseId; 

    [MarshalAs(UnmanagedType.BStr)] 
    public string Telephone1; 

    [MarshalAs(UnmanagedType.BStr)] 
    public string Telephone2; 
} 

byte[] buffer = new byte[stream.Length]; 
stream.Read(buffer, 0, (int)stream.Length); 
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); 
T stuff = (PatientStruct)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T)); 
handle.Free(); 

但是,我在調用Marshal.PtrToStructure時遇到了AccessViolationException。

有什麼建議嗎?

回答

2

首先,你的結構不應該是一個結構,而是一個類。結構用於代表單個值的小型不可變類型。

根據需要製作一個數據類型元帥真的很棘手,而且因爲你沒有在做互操作,所以你根本不需要編組。使用BinaryReader從文件中讀取數據更容易。

簡單數據類型可以是直斷讀取,並且字符串可以讀這樣的:

string value = reader.ReadChars(reader.ReadShort()); 

打開閱讀器時,指定一個適當的單字節編碼,例如窗口1252。

5

Marshal.PtrToStructure期待buffer充滿指向字符串的指針。我不認爲Marshal可以用來做你想做的。

相反,您需要確定二進制文件格式並手動編寫代碼。看看BinaryReader課程。

編輯:如果卡住了,可以添加對Microsoft.VisualBasic.dll的引用並使用FileSystem.FileGetObject方法。這與VB6中的Get關鍵字的行爲相同。

+1

+1 FileSystem.FileGetObject這可能是最簡單的方法。從幫助中「如果讀入的變量是一個字符串,默認情況下FileGetObject讀取一個包含字符串長度的雙字節描述符,然後讀取進入變量的數據」問題中的十六進制視圖確認字符串已寫入像這樣:以字節爲單位的字符串長度,然後是字符串。字符串編碼將是您的Windows ANSI編碼,如果您位於西歐(?),則可能是Windows 1252 – MarkJ 2010-12-13 18:01:29