You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C#将结构体数组克隆到二进制文件?能否复用VB.net相关方法?

C# 替代 VB.NET 的 FilePut/FileGet 实现方案

首先明确:C# 没有直接对应 VB.NET 中 FilePut/FileGet 的内置函数,这两个是VB为兼容旧版本保留的专属API。不过你可以通过以下几种方式实现类似功能,甚至有更符合C#开发习惯的方案:

一、模拟VB的FilePut/FileGet行为(兼容VB生成的文件)

如果需要读取VB用FilePut生成的二进制文件,或者生成能被VB的FileGet读取的文件,可以借助System.Runtime.InteropServices.Marshal类实现结构体与字节数组的互转,再通过文件流完成读写。

示例代码:

  1. 定义和VB内存布局一致的结构体:
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, Pack = 1)] // Pack=1匹配VB默认内存对齐规则
public struct UserData
{
    public int Id;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    public string Name;
    public int Age;
}
  1. 结构体转字节数组工具方法:
public static byte[] StructToBytes<T>(T structure) where T : struct
{
    int size = Marshal.SizeOf(structure);
    byte[] buffer = new byte[size];
    IntPtr ptr = Marshal.AllocHGlobal(size);
    try
    {
        Marshal.StructureToPtr(structure, ptr, false);
        Marshal.Copy(ptr, buffer, 0, size);
    }
    finally
    {
        Marshal.FreeHGlobal(ptr);
    }
    return buffer;
}
  1. 字节数组转结构体工具方法:
public static T BytesToStruct<T>(byte[] buffer) where T : struct
{
    int size = Marshal.SizeOf<T>();
    IntPtr ptr = Marshal.AllocHGlobal(size);
    try
    {
        Marshal.Copy(buffer, 0, ptr, size);
        return Marshal.PtrToStructure<T>(ptr);
    }
    finally
    {
        Marshal.FreeHGlobal(ptr);
    }
}
  1. 读写结构体数组到文件:
// 写入结构体数组
public static void WriteStructArrayToFile<T>(string filePath, T[] array) where T : struct
{
    using (FileStream fs = new FileStream(filePath, FileMode.Create))
    {
        foreach (var item in array)
        {
            byte[] bytes = StructToBytes(item);
            fs.Write(bytes, 0, bytes.Length);
        }
    }
}

// 读取结构体数组
public static T[] ReadStructArrayFromFile<T>(string filePath) where T : struct
{
    List<T> list = new List<T>();
    int structSize = Marshal.SizeOf<T>();
    using (FileStream fs = new FileStream(filePath, FileMode.Open))
    {
        byte[] buffer = new byte[structSize];
        while (fs.Read(buffer, 0, structSize) == structSize)
        {
            list.Add(BytesToStruct<T>(buffer));
        }
    }
    return list.ToArray();
}

二、更符合C#风格的手动序列化(灵活可控)

如果不需要和VB的文件格式兼容,推荐用BinaryReader和BinaryWriter手动读写结构体的每个字段,这种方式无需依赖互操作,更安全且易于维护。

示例代码:

  1. 带读写逻辑的结构体定义:
public struct UserData
{
    public int Id;
    public string Name;
    public int Age;

    // 写入当前结构体到BinaryWriter
    public void Write(BinaryWriter writer)
    {
        writer.Write(Id);
        writer.Write(Name); // BinaryWriter自动处理字符串长度标识
        writer.Write(Age);
    }

    // 从BinaryReader读取并生成结构体实例
    public static UserData Read(BinaryReader reader)
    {
        return new UserData
        {
            Id = reader.ReadInt32(),
            Name = reader.ReadString(),
            Age = reader.ReadInt32()
        };
    }
}
  1. 读写结构体数组:
// 写入数组到文件
public static void WriteUserDataArray(string filePath, UserData[] array)
{
    using (FileStream fs = new FileStream(filePath, FileMode.Create))
    using (BinaryWriter writer = new BinaryWriter(fs))
    {
        // 先写入数组长度,读取时可直接确定元素数量
        writer.Write(array.Length);
        foreach (var item in array)
        {
            item.Write(writer);
        }
    }
}

// 从文件读取数组
public static UserData[] ReadUserDataArray(string filePath)
{
    using (FileStream fs = new FileStream(filePath, FileMode.Open))
    using (BinaryReader reader = new BinaryReader(fs))
    {
        int length = reader.ReadInt32();
        UserData[] array = new UserData[length];
        for (int i = 0; i < length; i++)
        {
            array[i] = UserData.Read(reader);
        }
        return array;
    }
}

三、不推荐的方案:BinaryFormatter

曾经可以用BinaryFormatter直接序列化结构体数组,但该API已被标记为过时,存在严重安全漏洞(可能被利用反序列化恶意数据),因此强烈不建议使用。


内容的提问来源于stack exchange,提问作者sam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 14:35:20