繁体   English   中英

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

[英]Is there a BinaryReader in C++ to read data written from a BinaryWriter in C#?

我已经用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 ++,而intellisense甚至看起来都不像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”到什么位置,我都会收到完全相同的值。

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

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

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

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

编辑2
从关闭的流中读取也将导致未定义的行为。 您不能调用fin.close(),然后仍然希望能够从中读取。

这可能与问题无关,但...

创建BinaryWriter时,默认情况下是使用UTF-8编写char 这意味着它们中的一些可能会超过一个字节,从而使您的查找工作中断。

您可以通过使用2参数构造函数指定编码来避免这种情况。 System.Text.ASCIIEncoding的实例与默认情况下C / C ++使用的实例相同。

如果有帮助,我会在这里介绍BinaryWriter如何写入数据。

已经有一段时间了,但我会引用它,希望它是准确的:

  • Int16被写为2个字节并被填充。
  • Int32编写为Little Endian,零填充
  • 浮点数更为复杂:它需要一个浮点数并对其进行解引用,从而获得内存地址的内容(为十六进制)

您的C ++代码段中有很多错误。 您不应将二进制阅读与格式化阅读混合使用:

  // The file is closed after this line. It is WRONG to read from a closed file.
  fin.close();

  if(!strncmp("AB", memblock, 2)){ 
   printf("test. This works."); 
  }

  fin.seekg(2); // You are moving the "get pointer" of a closed file
  int i;

  // Even if the file is opened, you should not mix formatted reading
  // with binary reading. ">>" is just an operator for reading formatted data.
  // In other words, it is for reading "text" and converting it to a 
  // variable of a specific data type.
  fin >> i;

暂无
暂无

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

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