c# - C++ 中是否有 BinaryReader 来读取从 C# 中的 BinaryWriter 写入的数据?

标签 c# c++ file-io binaryfiles binaryreader

我已经在 C# 中使用 BinaryWriter 将多个 int、char[] 等写入数据文件。使用 BinaryReader(在 C# 中)读回文件,我可以完美地重新创建文件的所有部分。

但是,尝试用 C++ 读回它们会产生一些可怕的结果。我正在使用 fstream 尝试读回数据,但数据没有正确读入。在 C++ 中,我使用 ios::in|ios::binary|ios::ate 设置了一个 fstream,并使用 seekg 定位我的位置。然后我读取接下来的四个字节,它们被写为整数“16”(并正确读入 C#)。这在 C++ 中读作 1244780(不是内存地址,我检查过)。为什么会这样?在 C++ 中是否有 BinaryReader 的等价物?我注意到它在 msdn 上提到过,但对我来说那是 Visual C++ 和智能感知甚至看起来都不像 C++。

写入文件的示例代码(C#):

    public static void OpenFile(string filename)
    {
        fs = new FileStream(filename, FileMode.Create);
        w = new BinaryWriter(fs);

    }

    public static void WriteHeader()
    {
        w.Write('A');
        w.Write('B');
    }

    public static byte[] RawSerialize(object structure)
    {
        Int32 size = Marshal.SizeOf(structure);
        IntPtr buffer = Marshal.AllocHGlobal(size);
        Marshal.StructureToPtr(structure, buffer, true);
        byte[] data = new byte[size];
        Marshal.Copy(buffer, data, 0, size);
        Marshal.FreeHGlobal(buffer);
        return data;
    }

    public static void WriteToFile(Structures.SomeData data)
    {
        byte[] buffer = Serializer.RawSerialize(data);
        w.Write(buffer);
    }

我不确定如何向您展示数据文件。

读回数据的例子(C#):

        BinaryReader reader = new BinaryReader(new FileStream("C://chris.dat", FileMode.Open));
        char[] a = new char[2];
        a = reader.ReadChars(2);
        Int32 numberoffiles;
        numberoffiles = reader.ReadInt32();
        Console.Write("Reading: ");
        Console.WriteLine(a);
        Console.Write("NumberOfFiles: ");
        Console.WriteLine(numberoffiles);

我想在 C++ 中执行此操作。初始尝试(在第一个整数处失败):

 fstream fin("C://datafile.dat", ios::in|ios::binary|ios::ate);
 char *memblock = 0;
 int size;
 size = 0;
 if (fin.is_open())
 {
  size = static_cast<int>(fin.tellg());
  memblock = new char[static_cast<int>(size+1)];
  memset(memblock, 0, static_cast<int>(size + 1));

  fin.seekg(0, ios::beg);
  fin.read(memblock, size);
  fin.close();
  if(!strncmp("AB", memblock, 2)){ 
   printf("test. This works."); 
  }
  fin.seekg(2); //read the stream starting from after the second byte.
  int i;
  fin >> i;

编辑:似乎无论我在什么位置使用“seekg”,我都会收到完全相同的值。

最佳答案

您意识到 char 在 C# 中是 16 位而不是 C# 中通常的 8 位。这是因为 C# 中的 char 旨在处理 Unicode 文本而不是原始数据。因此,使用 BinaryWriter 写入字符将导致写入 Unicode 而不是原始字节。

这可能导致您错误地计算了整数的偏移量。我建议您在十六进制编辑器中查看该文件,如果您无法解决问题,请在此处发布文件和代码。

编辑1
关于您的 C++ 代码,请勿使用 >> 运算符从二进制流中读取。将 read() 与您要读取的 int 地址一起使用。

int i;
fin.read((char*)&i, sizeof(int));

EDIT2
从关闭的流中读取也会导致未定义的行为。您不能调用 fin.close() 然后仍然期望能够从中读取数据。

关于c# - C++ 中是否有 BinaryReader 来读取从 C# 中的 BinaryWriter 写入的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1525580/

相关文章:

c# - 使用 .Select() 时多次检查 null

c++ - 复制抽象基类的对象

c - 虚拟化 C 的 FILE* 接口(interface)的可行性如何?

c# - 如何获取具有指定名称的 DataMemberAttribute 的属性?

C# OpenXML SDK - 从幻灯片母版插入新幻灯片

c# - 以编程方式创建缓动函数 C#

c++ - 乘法 : uint vs float

c++ - 创建一个接受链表作为输入的合并排序

shell - 如何获取大文件的行数,至少5G

android - 如何在带有文件名的 ListView 中显示文件大小