以二进制格式写文件
Write file in binary format
我正在尝试以二进制格式编写文件。我有以下代码,但它将文件保存在文本格式中。
#include <iostream>
#include <fstream>
using namespace std;
int main(){
std::string ref = "Ecoli. 123";
unsigned int size = 124;
std::ofstream supp_info_output("binary_file", std::ios::out | std::ios::binary); // saving file
supp_info_output << ref << std::endl;
supp_info_output << size << std::endl;
supp_info_output.close();
std::ifstream supp_info_input("binary_file", std::ios::in | std::ios::binary); // loading file
std::string supp_info_line;
while( std::getline( supp_info_input, supp_info_line ).good() ){
std::cout << supp_info_line << std::endl;
}
supp_info_input.close();
}
在代码中,我正在编写一些数据,然后再次读取数据。阅读和写作没有问题,但是我需要二进制格式的文件。
使用::写入二进制数据和ifstream ::阅读以阅读它们。请注意,您应该节省字符串的长度,因为您应该知道要进一步读取多少个字节。
std::string ref = "Ecoli. 123";
unsigned int size = 124;
std::ofstream supp_info_output("binary_file", std::ios::out | std::ios::binary); // saving file
unsigned int stringLength = ref.length();
supp_info_output.write( (char*)( &stringLength ), sizeof( stringLength ) );
supp_info_output.write( ref.c_str(), ref.length() );
supp_info_output.write( (char*)( &size ), sizeof( size ) );
supp_info_output.close();
这是阅读的方法:
std::string ref;
unsigned int size;
std::ifstream supp_info_input("binary_file", std::ios::in | std::ios::binary); // loading file
unsigned int stringLength;
supp_info_input.read( (char*)( &stringLength ), sizeof( stringLength ) );
ref.resize( stringLength );
supp_info_input.read( (char*)ref.c_str(), stringLength );
supp_info_input.read( (char*)( &size ), sizeof( size ) );
supp_info_input.close();
,如等待中的答案所述,我不喜欢为每个输出语句编写很多代码。取而代之的是,我更喜欢将移位操作员过载,以使用户代码容易且较小的错误容易容易出现。
作为开始点,给出了以下示例。并非所有可能的过载都可能出现,而二进制文件类也少于"准备生产"。它仅作为启动自己的调查的可编译起点。
请记住:二进制文件不是便携式的,二进制表示形式可以从编译器/libc/其他版本的版本更改。它还取决于系统的OS和Endianess,以及架构(32 vs 64位(和许多其他体系。
因此,除非您编写具有定义/out格式定义的处理程序方法,否则通常不应使用二进制数据来使数据持续使用。我的示例简单地写入非常愚蠢的数据存储的记忆,并提到了所有问题。随时为可交换二进制格式启动自己的"完美"实现。
但是,有人应该使用准备好使用无处不在的实现。搜索"序列化器",您会发现像Boost Serialize和其他许多其他LIB一样。
#include <fstream>
#include <cstring>
class BinaryOut: public std::ofstream
{
public:
BinaryOut( const char* fname ):
std::ofstream( fname, std::ios::binary )
{}
};
// use a generic func to use for everything which not handled in special way
template < typename DataType >
BinaryOut& operator << ( BinaryOut& out, const DataType& data )
{
out.write( (char*)&data, sizeof( DataType ));
return out;
}
// if pointer type, write not pointer but values which pointer points to:
template < typename DataType >
BinaryOut& operator << ( BinaryOut& out, const DataType*& data )
{
out.write( (char*)data, sizeof( DataType ));
return out;
}
// special case for char ptr ( old style c string ) which ends with ' '
// use old style c here ( no std::string is involved )
BinaryOut& operator << ( BinaryOut& out, const char* ptr )
{
out.write( ptr, strlen( ptr ));
return out;
}
// may be some more overloads for << if needed...
int main()
{
BinaryOut out("example.bin");
int i=123;
double d=9.876;
double* ptrd=&d;
const char* dummy = "Ptr to Text";
out << i << d << ptrd << "Hallo, this is a test" << dummy;
}
它比以二进制编写数据要困难得多。我建议使用C文件 *接口,因为许多C 程序员过载&lt;&lt;>>以文本模式插入和提取更高级别的对象。当您去二进制时,您会失去那个。
要插入一个整数,您需要知道它是16位还是32位,大端或小居民。然后,您使用换档,掩码和呼叫fputc((直接编写字节。要插入ASCIIZ字符串,请类似地致电fputc并确保您编写nul。
@klaus是正确的,如果将int传递给&lt;&lt;在二进制文件中,它只需写入文本即可。如果您想编写二进制文件以用&lt;&lt;进行归档,则应将字节流传递到&lt;&lt;。例如,在您的代码中,您需要每次使用&lt;&lt;然后将二进制INT写入您的文件中。您可以检查以下代码:
#include "stdafx.h"
#include <iostream>
#include <fstream>
using namespace std;
union data {
int i;
char bytes[4];
};
int main(){
data src;
src.i = 0xabcddcba;
std::ofstream supp_info_output("binary_file", ios::out | ios::binary); // saving file
supp_info_output << src.bytes[0];
supp_info_output << src.bytes[1];
supp_info_output << src.bytes[2];
supp_info_output << src.bytes[3];
supp_info_output.close();
data dst;
dst.i = 0;
std::ifstream supp_info_input("binary_file", ios::in | ios::binary); // loading file
supp_info_input >> dst.bytes[0];
supp_info_input >> dst.bytes[1];
supp_info_input >> dst.bytes[2];
supp_info_input >> dst.bytes[3];
supp_info_input.close();
std::cout << ((src.i == dst.i)?"Pass check.":"Failed check.") << std::endl;
getchar();
}
我认为&lt;&lt;在二进制文件模式下,在二进制文件模式下,无论其类型如何,都应将所有内容视为字节流,例如int,double,short int,...等。
- 文件格式的编写解释器(C++ Arduino)
- 如何使用 lldb 在曼扎罗中调试 lz4 文件格式的核心转储?
- Assimp - 如何使用任何文件格式导入带有纹理的网格?
- boost::p rogram_options 配置文件格式
- 如何启用libMagick++以保存.png文件格式
- 生成库失败:无法识别文件格式;作为链接器脚本处理
- 有没有更好的方法来使用比特流解码文件格式?
- MySQL C++连接器:添加符号时出错:文件格式无法识别
- Qt解析自定义文件格式
- ADTF 录制文件格式
- /usr/bin/ld找不到标头:未识别的文件格式
- C 库从3D文件格式(例如STL)获得常规网格
- 随机访问文件格式,用于分层组织的二进制文件和文本文件
- C OPENCV 3.4 / FFMPEG 3.4.1 VIDEOWRITER和MP4输出文件格式
- 具有挑战性的数据文件格式,需要将其读取为包含类对象的数组的VAR
- GDB错误不以可执行格式:未识别的文件格式
- 如何获取 C++/Qt 格式的文件格式
- GetText PO文件格式
- 如何在 c++ 中从".in"格式的文件中获取输入?此代码进入无限循环,但适用于".txt"文件格式
- 用于将三维模型导入OpenGL/C++项目的推荐文件格式和图形库