【问题标题】:Read variable sized string from binary file (VB6 vs. C#)从二进制文件中读取可变大小的字符串(VB6 与 C#)
【发布时间】:2010-12-14 00:15:06
【问题描述】:

我有一个包含以下内容的二进制文件:

以下代码用于在旧的 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。

有什么建议吗?

【问题讨论】:

    标签: c# .net vb6 binary


    【解决方案1】:

    Marshal.PtrToStructure 期望 buffer 充满指向字符串的指针。我不认为Marshal 可以用来做你想做的事。

    相反,您需要确定二进制文件格式并为此手动编写代码。看看BinaryReader 类。

    编辑:如果遇到困难,可以添加对 Microsoft.VisualBasic.dll 的引用并使用 FileSystem.FileGetObject 方法。这与 VB6 中的 Get 关键字的行为相同。

    【讨论】:

    • +1 for FileSystem.FileGetObject 这可能是最简单的方法。从帮助“如果要读入的变量是字符串,默认情况下 FileGetObject 读取包含字符串长度的两字节描述符,然后读取进入变量的数据”您问题中的十六进制视图确认字符串已写入像这样:字符串的长度(以字节为单位),然后是字符串。字符串编码将是您的 Windows ANSI 编码,如果您位于西欧,则可能是 Windows 1252 (?)
    【解决方案2】:

    首先,你的结构根本不应该是一个结构,而是一个类。结构适用于表示单个值的小型不可变类型。

    完全按照您的意愿编组数据类型确实很棘手,而且由于您不进行互操作,因此您根本不需要编组。使用BinaryReader 从文件中读取数据更容易。

    简单的数据类型可以直接读取,字符串可以这样读取:

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

    在打开阅读器时指定适当的单字节编码,例如 windows-1252。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-18
      • 1970-01-01
      • 2012-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多