繁体   English   中英

使用c#将结构中的字节写入文件

[英]Writing bytes from a struct into a file with c#

大家,早安!

我在这里遇到了一个新问题。 我必须写下来自我在系统中声明的结构的数据。

我创建的结构只有两个字段,我用来稍后将其转换为字节。

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct MyStructData
{
    public short Id;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    public string Name;
}

我使用以下代码以字节为单位转换此结构:

private byte[] getBytes(MyStructData aux)
{
    int length = Marshal.SizeOf(aux);
    IntPtr ptr = Marshal.AllocHGlobal(length);
    byte[] myBuffer = new byte[length];

    Marshal.StructureToPtr(aux, ptr, true);
    Marshal.Copy(ptr, myBuffer, 0, length);
    Marshal.FreeHGlobal(ptr);

    return myBuffer;
}

此函数用于转换 MyStructData 类型元素的 List 结构中的每个元素,其中我拥有要发送到另一台机器的所有寄存器,并使用下面粘贴的代码执行此操作:

string saveToFilePath = "D:\\" + filename;
Stream myStream = myFtpRequest.GetRequestStream();

using (FileStream myFileStream = new FileStream(saveToFilePath, FileMode.Create))
{
    foreach (MyStructData myData in myStructDataList)
    {
        int length = 2048;
        byte[] newBuffer = new byte[length];
        newBuffer = getBytes(myCust);

        int len = 0;
        int bytesRead = 0;

        myFileStream.Write(newBuffer, 0, len);
        bytesRead += len;
    }

    myFileStream.Close();
}

我的问题是我看到我的新文件是空的,我不明白为什么它没有获取我的字节信息。 我已经检查了 List 是否带有数据,并且我还检查了我的字节转换功能是否也能正常工作,但我无法直截了当地查看导致我的文件为空的原因。

如果有人知道隧道尽头的光,我将非常感谢您的帮助!

编辑现在我有另一种方法将数据写入文件,并且效果很好:

using (Stream stream = new FileStream(saveToFilePath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
{
    using (BinaryWriter writer = new BinaryWriter(stream, Encoding.Default))
    {
        // get all data
        foreach (MyStructData myData in myStructDataList)
        {
            byte[] newBuffer = getBytes(cd);
            writer.Write(newBuffer);
        }
    }
}

FileStream.Write的第三个参数是要写入的字节数。 它不应该是 0。

string saveToFilePath = "D:\\" + filename;
Stream myStream = myFtpRequest.GetRequestStream();

int bytesWritten = 0;
using (FileStream myFileStream = new FileStream(saveToFilePath, FileMode.Create))
{
    foreach (MyStructData myData in myStructDataList)
    {
        newBuffer = getBytes(myData);
        myFileStream.Write(newBuffer, 0, newBuffer.Length);
        bytesWritten += newBuffer.Length;
    }
}

我认为您不应该将数据写入这样的文件。 对于这样的简单结构,最好使用BinaryFormatter

这是一个例子。 首先,您需要通过添加[Serializable]属性使MyStructData序列[Serializable]

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
[Serializable]
public struct MyStructData
{
    public short Id;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    public string Name;
}

然后,您可以将这些结构的列表写入文件,如下所示:

List<MyStructData> data = new List<MyStructData>();

for (short i = 0; i < 100; ++i)
    data.Add(new MyStructData{Id = i, Name = i.ToString()});

string filename = "C:\\test\\test.data";

using (var file = File.OpenWrite(filename))
{
    var writer = new BinaryFormatter();
    writer.Serialize(file, data); // Writes the entire list.
}

你可以像这样读回它们:

using (var file = File.OpenRead(filename))
{
    var reader = new BinaryFormatter();
    data = (List<MyStructData>) reader.Deserialize(file); // Reads the entire list.
}

foreach (var item in data)
    Console.WriteLine("Id = {0}, Name = {1}", item.Id, item.Name);

如果您将编组添加到结构的唯一原因是您可以在文件中写入和读取它,那么您可以将其删除,以便您的结构看起来像这样:

[Serializable]
public struct MyStructData
{
    public short Id;
    public string Name;
}

[编辑]

我来自未来注意到BinaryFormatter 现在被认为是不安全的

BinaryFormatter 类型是危险的,不建议用于数据处理。 应用程序应该尽快停止使用 BinaryFormatter,即使他们认为他们正在处理的数据是值得信赖的。 BinaryFormatter 不安全,无法确保安全。

一种更好的现代二进制序列化格式是通过 NuGet 提供的MessagePack-CSharp

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM