我正在使用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?
答案 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::list
是doubly linked list
,其中包含额外的指针,因此直接fread/memcpy
可能无法提供您在c#片段中存储的内容。