特定于应用程序的数据以及如何处理它?

时间:2011-05-22 04:11:40

标签: c# data-structures binary binary-data

我很好奇应用程序如何生成与应用程序本身一起使用的自己的数据。例如,如果您使用任何类型的PC游戏的保存文件或某种程序为BitTorrent应用程序生成Photoshop的PSD文件或.torrent文件等二进制数据,我会假设它们都是特定于相应的应用程序和作者该应用程序编程了这个数据的创建方式。我的第一个问题是:这是真的吗?我99%肯定它是二进制数据,因为当在Notepad ++中打开PSD文件或.torrent文件时,很容易看出人类无法读取它......

我的第二个问题是:如果我想创建一个以二进制格式生成自己的数据的应用程序(没有纯文本或任何易于操作的东西),我将如何处理这些数据?我可以模糊地生成这些数据并将其保存为二进制格式的文件,但是当我再次需要应用程序时,我真的不知道如何处理这些数据。由于这种类型的数据不是纯文本,不能被视为字符串或类似的东西,应用程序如何创建和处理/解析自己的二进制数据(或一般的任何二进制数据)?

我可以清楚地看到,当您打开PSD文件时,Photoshop会打开并显示所包含的PSD文件。但是许多应用程序如何处理这些格式?我只是没有看到如何解析这些特定数据(或一般的二进制数据),并以编程方式执行您想要的操作。

3 个答案:

答案 0 :(得分:4)

嗯,举一个简单的例子,我们来看一下位图。

位图具有标准文件结构,由info头和文件头定义。

在维基百科文章(链接: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);

答案 1 :(得分:3)

在MSDN上阅读Binary Serialization。 .Net Framework在很大程度上有助于实现这一目标。

答案 2 :(得分:2)

是的,许多应用程序利用某些特定于应用程序的二进制格式,这些格式无法轻易操作。要创建自己的二进制格式,有一些选项:

  1. Binary Serialization Technique
  2. 使用IO类手动读取和写入字节,实际上是creating a random access file.