【发布时间】:2013-02-04 03:52:07
【问题描述】:
我正在编写一个资源文件,我想从各种常见文件(例如 .JPG、.BMP)中插入一堆数据,并且我希望它是二进制文件。 我将编写一些代码来稍后按索引组织检索这些数据,这就是我目前得到的:
float randomValue = 23.14f;
ofstream fileWriter;
fileWriter.open("myFile.dat", ios::binary);
fileWriter.write((char*)&randomValue, sizeof(randomValue));
fileWriter.close();
//With this my .dat file, when opened in notepad has "B!¹A" in it
float retrieveValue = 0.0f;
ifstream fileReader;
fileReader.open("myFile.dat", ios::binary);
fileReader.read((char*)&retrieveValue, sizeof(retrieveValue));
fileReader.close();
cout << retrieveValue << endl; //This gives me exactly the 23.14 I wanted, perfect!
虽然这很好用,但我想了解那里到底发生了什么。 我正在将randomValue的地址转换为char*,并将该地址中的值写入文件?
我也很好奇,因为我需要为数组执行此操作,而我无法执行此操作:
int* myArray = new int[10];
//fill myArray values with random stuff
fileWriter.open("myFile.dat", ios::binary);
fileWriter.write((char*)&myArray, sizeof(myArray));
fileWriter.close();
据我了解,这只会在文件中写入第一个地址的值,而不是所有数组。因此,为了测试,我试图简单地将变量转换为 char* ,然后将其写入文件,然后转换回变量以查看是否正确检索了值,所以我同意:
int* intArray = new int[10];
for(int i = 0; i < 10; i++)
{
cout << &intArray[i]; //the address of each number in my array
cout << intArray[i]; //it's value
cout << reinterpret_cast<char*>(&intArray[i]); //the char* value of each one
}
但出于某种我不知道的原因,当我运行此代码时,我的计算机“发出哔哔声”。在数组期间,我还将这些保存到 char* 并尝试转换回 int,但我没有得到预期的结果,我得到了一些非常长的值。 比如:
float randomValue = 23.14f;
char* charValue = reinterpret_cast<char*>(&randomValue);
//charValue contains "B!¹A" plus a bunch of other (un-initiallized values?) characters, so I'm guessing the value is correct
//Now I'm here
我想把charValue转回randomValue,怎么办?
编辑:下面的答案中包含有价值的信息,但它们并不能解决我的(原始)问题。我正在测试这些类型的转换,因为我正在编写一个代码,我将选择一堆资源文件,例如 BMP、JPG、MP3,并将它们保存在一个按一些标准组织的 .DAT 文件中,我还没有完全想通了。
稍后,我将使用这个资源文件来读取这些内容并将其加载到我正在编码的程序(游戏)中。
我仍在考虑的标准,但我想知道是否可以这样做:
//In my ResourceFile.DAT
[4 bytes = objectID][3 bytes = objectType (WAV, MP3, JPG, BMP, etc)][4 bytes = objectLength][objectLength bytes = actual objectData]
//repeating this until end of file
然后在读取资源文件的代码中,我想做这样的事情(未经测试):
ifstream fileReader;
fileReader.open("myFile.DAT", ios::binary);
//file check stuff
while(!fileReader.eof())
{
//Here I'll load
int objectID = 0;
fileReader((char*)&objectID, 4); //read 4 bytes to fill objectID
char objectType[3];
fileReader(&objectType, 3); //read the type so I know which parser use
int objectLength = 0;
fileReader((char*)&objectLength, 4); //get the length of the object data
char* objectData = new char[objectLength];
fileReader(objectData, objectLength); //fill objectData with the data
//Here I'll use a parser to fill classes depending on the type etc, and move on to the next obj
}
目前我的代码正在处理原始文件(BMP、WAV 等)并将它们填充到类中,我想知道如何将这些文件中的数据保存到二进制数据文件中。 例如,我管理 BMP 数据的类有这样的:
class FileBMP
{
public:
int imageWidth;
int imageHeight;
int* imageData;
}
当我加载它时,我会调用:
void FileBMP::Load(int iwidth, int iheight)
{
int imageTotalSize = iwidth * iheight * 4;
imageData = new int[imageTotalSize]; //This will give me 4 times the amount of pixels in the image
int cPixel = 0;
while(cPixel < imageTotalSize)
{
imageData[cPixel] = 0; //R value
imageData[cPixel + 1] = 0; //G value
imageData[cPixel + 2] = 0; //B value
imageData[cPixel + 3] = 0; //A value
cPixel += 4;
}
}
所以我有这个单维数组,其中包含每个像素 [RGBA] 格式的值,稍后我将使用它在屏幕上绘图。 我希望能够将这个数组保存为我在上面所说的计划的二进制数据格式,然后读取它并填充这个数组。
我认为这样的代码要求太高了,所以我想了解将这些值保存到二进制文件中然后读回以填充它需要知道什么。
抱歉,帖子太长了!
edit2:我通过第一次编辑解决了我的问题...感谢您提供宝贵的信息,我也知道我想要什么!
【问题讨论】:
标签: c++ binary binaryfiles