Запись двоичного файла в C #, а затем чтение того же файла в переполнении стека

Я пишу двоичный файл в C # с использованием класса BinaryWriter

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);

Затем я пытаюсь использовать значение счетчика, чтобы определить размер списка, в котором будут храниться данные. Я не могу использовать массив, так как значение для количества будет отличаться в зависимости от файла, который читается.

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

fclose(LoadFile);

Код выше не работает. Я могу заставить счет быть прочитанным правильно, но команда memcpy вызывает нарушение доступа с 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 [] в данные структуры?

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
}
2

Другие решения

Вместо проблемы строкового типа данных, описанной в другом ответе, здесь есть еще одна вещь. std::list это doubly linked list который содержит дополнительные указатели по своей природе, так что прямой fread/memcpy Вероятно, не дает вам то, что вы сохранили в C # фрагмент.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector