Чтение двоичного файла целых чисел - PullRequest
0 голосов
/ 10 июня 2018

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

Вот как я пишу:

std::ofstream OutFile;
OutFile.open("encode.bin", std::ios::out | std::ios::binary);

for(int i = 0; i < all.size(); i++){
        int code = codes[i];
        OutFile.write(reinterpret_cast<const char *>(&code), sizeof(int));
}
OutFile.close();

А вот так выглядят мои .bin-файлы, когда я пишу числа: 65, 66, 66, 257, 258, 260

  Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F   
00000000: 41 00 00 00 42 00 00 00 42 00 00 00 01 01 00 00   
00000010: 02 01 00 00 04 01 00 00         

Есть липроблема с порядком байтов?Я вижу, что цифры поменялись местами.

И как я это читаю:

std::vector<int> allCodes;
std::ifstream inputD(file, std::ios::binary);

std::vector<char> buffer((
    std::istreambuf_iterator<char>(inputD)),
    (std::istreambuf_iterator<char>()));

for (auto a : buffer) {
    data.push_back(static_cast<int>(a));
    allCodes.push_back(a);
};

Когда я отображаю мой вектор, первые три числа (65, 66, 66) читаются правильно, с несколькими нулями между ними.

Вот как выглядит дисплей:

image

1 Ответ

0 голосов
/ 10 июня 2018

Прежде всего, вы не должны использовать reinterpret_cast здесь, из-за порядка байтов - вы теряете переносимость.Вы пишете целые числа длиной 4 байта в вашем случае.Затем вы пытаетесь прочитать числа в char , который имеет только 1 байт .Это объясняет, почему вы видите правильный вывод для первых трех чисел (они находятся в диапазоне от 0 до 255) и почему между ними есть несколько нулей.

Здесь я нашел какой-то фрагмент кода на своем жестком диске,это, вероятно, могло бы быть написано лучше, но это делает работу и немного безопаснее, чем ваше решение.

template<typename T> void ReadInteger(T &Output, const char* Buffer)
{
    static_assert(std::numeric_limits<T>::is_integer, "return type cannot be non-arithmetic or floating point");
    Output = 0;
    for(unsigned int i = 0; i<sizeof(T); i++)
    {
        Output <<= 8;
        Output |= Buffer[i];
    }
}

template<typename T> void WriteInteger(T Value, char* Buffer)
{
    static_assert(std::numeric_limits<T>::is_integer, "first parameter cannot be non-arithmetic or floating point");
    for(unsigned int i = 0; i<sizeof(T); i++)
    {
        Buffer[sizeof(T)-i-1] = static_cast<char>(Value&0xff);
        Value >>= 8;
    }
}

Пример использования:

int Value = 42;
char Buffer[sizeof(int)];
WriteInteger(Value, Buffer);
File.write(Buffer, sizeof(int));
// ...
File.read(Buffer, sizeof(int));
int a;
ReadInteger(a, Buffer);
...