【问题标题】:BinaryReader, BinaryFormatter - are they portable?BinaryReader、BinaryFormatter - 它们是可移植的吗?
【发布时间】:2015-05-24 19:40:24
【问题描述】:

在 C、C++ 中,如果您以二进制方式(例如 fwrite(&someInt,sizeof(int),1,fp))写入一个整数到文件,如果您想从不同的机器读取该整数,您需要考虑大量问题 - 例如,字节顺序问题、整数大小在其他计算机上可能会有所不同,浮点表示在不同计算机上可能会有所不同,负整数有不同的表示等。所以直接以二进制模式读写可能无法在不同计算机上工作。

在下面这个使用二进制阅读器(来自 MSDN)的示例中,上述问题是否也适用?

using System;
using System.IO;

class ConsoleApplication
{
    const string fileName = "AppSettings.dat";

    static void Main()
    {
        WriteDefaultValues();
        DisplayValues();
    }

    public static void WriteDefaultValues()
    {
        using (BinaryWriter writer = new BinaryWriter(File.Open(fileName, FileMode.Create)))
        {
            writer.Write(1.250F);
            writer.Write(@"c:\Temp");
            writer.Write(10);
            writer.Write(true);
        }
    }

    public static void DisplayValues()
    {
        float aspectRatio;
        string tempDirectory;
        int autoSaveTime;
        bool showStatusBar;

        if (File.Exists(fileName))
        {
            using (BinaryReader reader = new BinaryReader(File.Open(fileName, FileMode.Open)))
            {
                aspectRatio = reader.ReadSingle();
                tempDirectory = reader.ReadString();
                autoSaveTime = reader.ReadInt32();
                showStatusBar = reader.ReadBoolean();
            }

            Console.WriteLine("Aspect ratio set to: " + aspectRatio);
            Console.WriteLine("Temp directory is: " + tempDirectory);
            Console.WriteLine("Auto save time set to: " + autoSaveTime);
            Console.WriteLine("Show status bar: " + showStatusBar);
        }
    }
}

BinaryFormatter 类呢?

【问题讨论】:

  • 您是否假设在所有机器上都使用相同的可执行文件?如果您必须在每台机器上重新编译,那么您会遇到同样的问题,因为您为 autoSaveTime 定义了一个“int”。现在,如果您改用 Int32 就可以了。
  • @jdweng:我不确定你的意思,但说是 - 我假设相同的可执行文件。但我也可能指的是通过网络从一台计算机向另一台计算机发送一个整数,等等。我认为在 C# 中 int32 是 int 的别名 .. 那么为什么会有区别?
  • 如果您使用的是相同的可执行文件,那么整数大小的设置会内置到可执行文件中。所以它是便携的。是的,在 XP 上,整数始终是 32,但在 Win95 上不是,未来可能是 64。

标签: c# serialization binary


【解决方案1】:
  • BinaryWriter 的字节序已修复。它始终是小端。
  • 每种数据类型的整数大小始终相同:byte/sbyte 1Bshort/ushort 2Bint/uint 4Blong/ulong 8B
  • 浮点数和双精度数遵循 IEEE 标准
  • 使用BinaryReader/BinaryWriter 读写会带来相同的结果。从 C# 到 Java,您需要翻转所有传入字节,因为 Java 使用的是 BigEndian
  • BinaryFormatter 用于序列化或反序列化同一台 PC 上的对象。将数据从一台 PC 传输到另一台时不应使用它。

如果您使用两个 C# 应用程序,只需使用 BinaryReader/BinaryWriter,它们是可移植的。如果另一端没有使用 C# 编程,您很可能需要使用(或编写自己的)类来处理此类问题。

【讨论】:

  • BinaryFormatter 不是一个用于通过线路序列化数据的好系统,它在设计时考虑到了同一台机器内的 IPC。它对序列化对象的对象图中的任何程序集的版本更改都极为敏感,我听说过两台计算机由于与 .NET 相关的 Windows 更新补丁级别不同而无法通信的故事。
  • @ScottChamberlain:这是我的问题,是否可以使用 BinaryReader、BinaryWriter、BinaryFormatter 以便携式方式序列化数据
  • @user44333 读者和作者,是的。格式化程序,没有。还要注意BitConverter,该类也可以将事物转换为byte[],但BitConverter 对其运行的机器的字节序很敏感(无论计算机体系结构如何,BineryReader 和 Writer 总是使用小字节序)。
  • @ScottChamberlain:像 XML 这样的文本序列化是否保证可移植?所以我可以使用二进制读取器和写入器来序列化数据结构..
  • 是的,但是可以选择在构造函数中设置的文本编码。确保两边都设置为相同的值。
猜你喜欢
  • 2020-01-30
  • 1970-01-01
  • 2011-02-12
  • 1970-01-01
  • 2016-02-25
  • 1970-01-01
  • 2016-02-28
  • 1970-01-01
  • 2017-03-11
相关资源
最近更新 更多