在C#中编写二进制文件,然后在C ++中读取相同的文件

时间:2012-09-06 22:50:36

标签: c# c++ binaryfiles

我正在使用BinaryWriter类

在C#中编写二进制文件
using (var b = new System.IO.BinaryWriter(System.IO.File.Open("C:\\TextureAtlas0.txa", 
       System.IO.FileMode.Create)))
{
  int count;

  // Write the number of source rectangle entries
  count = textureAtlas.Rectangles.Count;

  b.Write(count);

  for (int i = 0; i < count; ++i)
  {
    b.Write(textureAtlas.SpriteNames[i]);
    b.Write(textureAtlas.Rectangles[i].X);
    b.Write(textureAtlas.Rectangles[i].Y);
    b.Write(textureAtlas.Rectangles[i].Width);
    b.Write(textureAtlas.Rectangles[i].Height);
  }
}

然后我尝试使用以下步骤将相同的文件读入C ++。

我有一个结构,它以与编写时相同的顺序保存数据。

struct TextureAtlasEntry 
{
    std::string name;
    int x;
    int y;
    int width;
    int height;
};

首先读取计数

int count;

fread(&count, sizeof(int), 1, LoadFile);
然后,我尝试使用计数值来确定将保存数据的列表大小。我似乎无法使用数组,因为count的值将根据读取的文件而有所不同。

std::list<TextureAtlasEntry> entries;
fread(&entries, sizeof(TextureAtlasEntry), count, LoadFile);

fclose(LoadFile);

上面的代码不起作用。我可以正确读取计数,但memcpy命令会导致fread和条目列表的访问冲突。

如何正确读取数据,是否应该将fread与C ++等效交换?

编辑:

我现在可以使用以下代码将整个二进制文件读入内存

ifstream::pos_type size;
char *memblock;

ifstream file ("TextureAtlas0.txa", ios::in|ios::binary|ios::ate);

if (file.is_open())
{
    size = file.tellg();
    memblock = new char[size];
    file.seekg (0, ios::beg);
    file.read (memblock, size);
    file.close();

    printf("File content is in memory");

    delete[] memblock;
}
else 
{
    printf("Unable to open file");
}

现在文件在内存中,如何将char []数据转换为struct data?

2 个答案:

答案 0 :(得分:2)

根据documentation,BinaryWriter(String)写...

  

以长度为前缀的字符串表示前缀为的字符串长度   字符串是包含其长度的单个字节或单词   串。此方法首先将字符串的长度写为UTF-7   编码无符号整数,然后将多个字符写入   通过使用BinaryWriter实例的当前编码进行流式传输。

在您的C ++代码中,您只是尝试读取结构大小的字节数,这与BinaryWriter使用的格式不同。

您使用.NET作为C ++代码吗?如果是这样,只需使用BinaryReader类来读取文件。

如果没有,你将不得不将读取分开一点。当您准备读取名称时,首先必须读取“UTF-7编码无符号整数”,然后读取更多字节以获取字符串。

修改

根据您在下面的评论,您似乎不会使用C ++ .NET,所以我认为您有两种选择。 1)以能够将其读入C ++的方式写出C#中的数据(使用固定长度的字符串)2)找出BinaryWriter.Write()写入数据的方式,以便您可以在C ++中正确读取它。

伪代码 - 我认为它是这样的。就像我在下面的评论中所说的那样,我的C ++生锈了,但这是基本的算法应该很接近。

read from file int num - number of items
for (i=0;i<num;i++){
   read int stringBytes - size of string
   read string stringBytes bytes - the name
   read int X4
   create your struct and add to list/array/dictionary
}

答案 1 :(得分:0)

而不是另一个答案中解释的字符串数据类型问题,这里还有一件事。 std::listdoubly linked list,其中包含额外的指针,因此直接fread/memcpy可能无法提供您在c#片段中存储的内容。