2

我正在使用 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 数据?

4

2 回答 2

2

根据文档, 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
}
于 2012-09-06T23:07:59.243 回答
0

而不是另一个答案中解释的字符串数据类型问题,这里还有一件事。std::list是一个doubly linked list本质上包含额外指针的,所以直接fread/memcpy可能不会给你你在 c# 片段中存储的内容。

于 2012-09-06T23:10:55.933 回答