有一段时间了,在尝试用C++写入文件缓冲区时,我遇到了一个非常奇怪的问题.问题只发生在MinGW上.当我在gcc/linux下编译时,一切都很好.
基本上,我正在将代码从内存缓冲区写入文件缓冲区,文件中的二进制表示最终与我编写的内存不同.不,以后没有修改该文件,我通过使用调试器在关闭文件后退出程序来确保这一点.我不知道这样的事情怎么可能,我甚至用valgrind来看看是否有任何内存分配问题,但是没有.
我将粘贴一些相关的代码.
/// a struct holding information about a data file
class ResourceFile {
public:
string name;
uint32 size;
char* data;
ResourceFile(string name, uint32 size);
};
ResourceFile::ResourceFile(string name, uint32 size)
: name(name), size(size)
{
// will be free'd in ResourceBuilder's destruction
data = (char*) malloc(size * sizeof(char));
}
/// Build a data resource from a set of files
class ResourceBuilder {
public:
ofstream out; ///< File to put the resource into
vector<ResourceFile> input; ///< List of input strings
/// Add a file from disk to the resource
void add_file(string filename);
/// Create a file that the resource will be written to
void create_file(string filename);
~ResourceBuilder();
};
void ResourceBuilder::create_file(string filename) {
// open the specified file for output
out.open(filename.c_str());
uint16 number_files = htons(input.size());
out.write((char*) &number_files, sizeof(uint16));
foreach(vector<ResourceFile>,input,i) {
ResourceFile& df = *i;
uint16 name_size = i->name.size();
uint16 name_size_network = htons(name_size);
out.write((char*) &name_size_network, sizeof(uint16));
out.write(i->name.c_str(),name_size);
uint32 size_network = htonl(i->size);
out.write((char*) &size_network, sizeof(i->size) );
out.write(i->data, i->size);
}
out.close();
/// \todo write the CRC
}
Run Code Online (Sandbox Code Playgroud)
以下是如何首先分配内存.这是一个可能的错误来源,因为我从其他地方复制了它而没有详细了解它,但老实说我不知道我分配内存的方法可能是文件缓冲输出与内存不同的原因我正在写作
void ResourceBuilder::add_file(string filename) {
// loads a file and copies its content into memory
// this is done by the ResourceFile class and there is a
// small problem with this, namely that the memory is
// allocated in the ResourceFile directly,
ifstream file;
file.open(filename.c_str());
filebuf* pbuf=file.rdbuf();
int size=pbuf->pubseekoff (0,ios::end,ios::in);
pbuf->pubseekpos (0,ios::in);
ResourceFile df(filename,size);
pbuf->sgetn (df.data,size);
file.close();
input.push_back(df);
}
Run Code Online (Sandbox Code Playgroud)
我真的没有想法.它也不是与我的编译器设置有关的错误,因为其他人在MinGW下编译代码会得到相同的错误.我在这一点上可以想到的唯一解释是MinGW的文件缓冲库本身的错误,但老实说我不知道.
您需要以二进制模式打开文件.当您在Windows上以文本模式打开它时,换行符(0x0A)将转换为CR/LF对(0x0D,0x0A).在Linux上你没有看到这个,因为Linux在文本文件中使用单个LF(0x0A)作为行终止符,因此不进行转换.
将ios::binary标志传递给ostream::open方法:
out.open(filename.c_str(), ios::out | ios::binary);
Run Code Online (Sandbox Code Playgroud)
您还应该在读取二进制文件时使用此标志,以便不执行相反的转换:
ifstream file;
file.open(filename.c_str(), ios::in | ios::binary);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
318 次 |
| 最近记录: |