Данные для конкретного приложения и как с ними обращаться? - PullRequest
2 голосов
/ 22 мая 2011

Мне любопытно, как приложения генерируют свои собственные данные, которые используются самим приложением.Например, если вы берете какой-либо файл сохранения для игры на ПК или какую-либо программу, которая генерирует двоичные данные, такие как PSD-файлы Photoshop или .torrent-файлы для приложений BitTorrent, я бы предположил, что они все специфичны для соответствующего приложения и что авторыэтого приложения запрограммировали способ создания этих данных.Мой первый вопрос: это правда?Я на 99% уверен, что это двоичные данные, потому что при открытии PSD-файла или .torrent-файла в Notepad ++ легко понять, что человек ничего не может прочитать ...

Мой второй вопросэто: если бы я хотел создать приложение, которое генерирует свои собственные данные в двоичном формате (без простого текста или чего-либо, что можно легко манипулировать), как бы мне поступить с этими данными?Я смутно представляю, как генерировать эти данные и сохранять их в файл в двоичном формате, но я действительно застрял в том, как бы я обработал эти данные, когда они снова понадобятся приложению.Поскольку этот тип данных не является простым текстом и не может рассматриваться как строка или что-то подобное, как приложения могут создавать и обрабатывать / анализировать свои собственные двоичные данные (или любые двоичные данные в целом)?

Очевидно, я вижу, что когда вы открываете PSD-файл, открывается Photoshop, и он отображает любой содержащийся PSD-файл.Но как многие приложения обрабатывают эти форматы?Я просто не вижу, как анализировать эти конкретные данные (или двоичные данные в целом) и программно делать с ними то, что вы хотите.

Ответы [ 3 ]

4 голосов
/ 22 мая 2011

Ну, в качестве простого примера, давайте возьмем растровые изображения.

Растровые изображения имеют стандартную файловую структуру, которая определяется информационным заголовком и заголовком файла.

В статье в википедии (ссылка: http://en.wikipedia.org/wiki/BMP_file_format) вы увидите, что заголовок информации имеет четко определенный формат, а также заголовок файла.

Каждый из них записывается в двоичном виде как есть, и читается в двоичном виде как есть. Затем собственно растровое изображение записывается в двоичном виде.

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

Посмотрите на сериализацию, это довольно широкая тема, и к этому есть множество подходов.

Редактировать: Вот пример кода (не оптимальный) для чтения (или записи с правильными изменениями) в растровых изображениях:

// Tell visual studio to align on 2-byte boundary
// Necessary so if you write to file, it only writes 14 bytes and not 16.
#pragma pack(2)
struct BMIH
{
    short bfType;
    long bfSize;
    short bfReserved0;
    short bfReserved1;
    long bOffbits;
};

#pragma pack(8)
struct BMFH
{
    long biSize;
    long biWidth;
    long biHeight;
    short biPlanes;
    short biBitCount;
    long biCompression;
    long biImageSize;
    long biXPelsPerMeter;
    long biYPelsPerMeter;
    long biClrUsed;
    long biClrImportant;
};



BMIH infoheader;
BMFH fileheader;

std::fstream file(filename.c_str(), std::ios::in | std::ios::binary);

// Read in info and file headers
file.read((char *) &infoheader, sizeof(infoheader));
file.read((char *) &fileheader, sizeof(fileheader));

    // Calculate size of image
int size = fileheader.biHeight * fileheader.biWidth;
int bytes = size * fileheader.biBitCount / 8;

    // Read in the image to a buffer
unsigned char data = new unsigned char[bytes];
file.read((char *) td.data, bytes);
    file.close();

Этот код на самом деле является радикальным упрощением и полностью игнорирует всевозможные проблемы, например, что происходит, если заголовки файлов или данные повреждены, если файл не является неполным, и т. Д. Но он просто предназначен для подтверждения концепции , На самом деле #pragmas - это визуальная студия, специально предназначенная для правильного выравнивания заголовков.

Когда мы записываем это в файл, мы можем фактически не сказать «Хорошо, теперь запишите это целое число». Вместо этого мы хотим записать его в двоичном формате. Например, код, который вы можете (но не должен) использовать для написания, будет выглядеть так:

// Assume for arguments sake these data structures came pre-filled
BMFH fileheader;
BMIH infoheader;
unsigned char *data; 
int size = fileheader.biHeight * fileheader.biWidth;
int bytes = size * fileheader.biBitCount / 8;

std::fstream file("MyImage.bitmap", std::ios::out | std::ios::binary);

file.write((char *) &infoheader, sizeof(BMIH));
file.write((char *) &fileheader, sizeof(BMFH));
file.write((char *) data, sizeof(unsigned char) * bytes);
3 голосов
/ 22 мая 2011

Читать на Двоичная сериализация на MSDN. .Net Framework помогает в этом.

2 голосов
/ 22 мая 2011

Да, многие приложения используют своего рода двоичные форматы, специфичные для приложений, которыми трудно манипулировать. Чтобы создать свой собственный двоичный формат, есть несколько вариантов:

  1. Техника двоичной сериализации
  2. Использование классов ввода-вывода для ручного чтения и записи байтов и фактически создание файла произвольного доступа.
...