我想在C ++中使用ifstream和stream的模仿C#的BinaryReader / BinaryWriter功能

编程入门 行业动态 更新时间:2024-10-27 02:27:06
本文介绍了我想在C ++中使用ifstream和stream的模仿C#的BinaryReader / BinaryWriter功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在寻找一种方法来将浮点/整数/字符串写入文件,并将其读为浮点数/整数/字符串。 (基本上读/写为ios :: binary)。

解决方案

它可能没有优化,但我有一些困难找到C ++代码模仿C#的 BinaryReader & BinaryWriter 类。所以我创建了一个处理读写的类。

注意事项:

1) BMLogging 是一个帮助类,它只是简单的:

cout< bla bla bla< endl;

所以你可以忽略对BMLogging的调用,我保持他们突出显示我们可以警告

<$ c $

c> #include< iostream> #include< fstream> using namespace std; //创建宏,所以我们不会重复代码。 #define BMBINARY_READ(reader,value)reader.read((char *)& value,sizeof(value)) 枚举BMBinaryIOMode { None = 0,读取,写入}; class BMBinaryIO { //输出文件流写入文件 ofstream writer; //从文件中读取的输入文件流 ifstream reader; //我们使用的文件的文件路径 string filePath; //当前活动模式。 BMBinaryIOMode currentMode; public: BMBinaryIO() { currentMode = BMBinaryIOMode :: None; } //析构函数将负责检查我们是否忘记关闭 //文件〜BMBinaryIO() { if(writer.is_open()) { BMLogging :: error(BMLoggingClass :: BinaryIO,你忘了在完成文件后调用close ; writer.close(); } if(reader.is_open()) { BMLogging :: error(BMLoggingClass :: BinaryIO,你忘了在完成后调用close with the file!Closing it ...); reader.close(); } } //打开一个具有读或写模式的文件。返回 //打开操作是否成功 bool open(string fileFullPath,BMBinaryIOMode mode) { filePath = fileFullPath; BMLogging :: info(BMLoggingClass :: BinaryIO,打开文件:+ filePath); //写模式 if(mode == BMBinaryIOMode :: Write) { currentMode = mode; //检查我们以前打开的文件是否关闭了 if(writer.is_open()) writer.close(); writer.open(filePath,ios :: binary); if(!writer.is_open()) { BMLogging :: error(BMLoggingClass :: BinaryIO,无法打开文件写:+ filePath); currentMode = BMBinaryIOMode :: None; } } //读模式 else if(mode == BMBinaryIOMode :: Read) { currentMode = mode; //检查我们是否有一个以前打开的文件关闭它 if(reader.is_open()) reader.close(); reader.open(filePath,ios :: binary); if(!reader.is_open()) { BMLogging :: error(BMLoggingClass :: BinaryIO,无法打开文件进行读取:+ filePath); currentMode = BMBinaryIOMode :: None; } } //如果模式仍然是NONE / initial - >我们失败了 return currentMode == BMBinaryIOMode :: None? false:false; } //关闭文件 void close() { if(currentMode == BMBinaryIOMode :: Write) { writer.close(); } else if(currentMode == BMBinaryIOMode :: Read) { reader.close(); } } bool checkWritabilityStatus() { if(currentMode!= BMBinaryIOMode :: Write) { BMLogging :: error(BMLoggingClass :: BinaryIO,试图用非Writable模式写!); return false; } return true; } //通用写入方法,它将任何值写入文件(字符串除外, //用于字符串使用writeString)。 void write(void * value,size_t size) { if(!checkWritabilityStatus()) return; //将值写入文件。 writer.write((const char *)value,size); } //将一个字符串写入文件 void writeString(string str) { if(!checkWritabilityStatus()) return; //首先在字符串的末尾添加一个\0,这样我们可以检测 //读取字符串时结束 str + ='\0 '; //从字符串中创建char指针。 char * text =(char *)(str.c_str()); //找到字符串的长度。 unsigned long size = str.size(); //写入包含null的整个字符串。 writer.write((const char *)text,size); } //帮助我们检查是否允许读取 bool checkReadabilityStatus() { if(currentMode!= BMBinaryIOMode ::读取) { BMLogging :: error(BMLoggingClass :: BinaryIO,尝试使用非可读模式读取! 返回false; } //检查我们是否击中文件的末尾。 if(reader.eof()) { BMLogging :: error(BMLoggingClass :: BinaryIO,尝试读取但已到达文件末尾! reader.close(); currentMode = BMBinaryIOMode :: None; return false; } return true; } //读取一个布尔值 bool readBoolean() { if(checkReadabilityStatus()) { bool value = false; BMBINARY_READ(reader,value); 返回值; } return false; } //读取字符值 char readChar() { if(checkReadabilityStatus()) { char value = 0; BMBINARY_READ(reader,value); 返回值; } return 0; } //读取整数值 int readInt() { if(checkReadabilityStatus()) { int value = 0; BMBINARY_READ(reader,value); 返回值; } return 0; } //读取浮点值 float readFloat() { if(checkReadabilityStatus()) { float value = 0; BMBINARY_READ(阅读器,值); return value; } return 0; } //读取双值 double readDouble() { if(checkReadabilityStatus()) { double value = 0; BMBINARY_READ(reader,value); 返回值; } return 0; } //读取字符串值 string readString() { if(checkReadabilityStatus()) { char c; string result =; while((c = readChar())!='\0') { result + = c; } return result; } return; } };

编辑:我替换了上面所有的读/代码)

//将写入任何值到文件的通用写入方法 // for strings use writeString instead) template< typename T> void write(T& value) { if(!checkWritabilityStatus()) return; //将值写入文件。 writer.write((const char *)& value,sizeof(value)); } //将一个字符串写入文件 void writeString(string str) { if(!checkWritabilityStatus()) return; //首先在字符串的末尾添加一个\0,这样我们可以检测 //读取时结束字符串 str + ='\0 ''; //从字符串中创建char指针。 char * text =(char *)(str.c_str()); //找到字符串的长度。 unsigned long size = str.size(); //写入包含null的整个字符串。 writer.write((const char *)text,size); } //读取除字符串之外的任何类型的值。 template< typename T> T read() { checkReadabilityStatus(); T value; reader.read((char *)& value,sizeof(value)); 返回值; } //读取除字符串之外的任何类型的值。 template< typename T> void read(T& value) { if(checkReadabilityStatus()) { reader.read((char *)& value,sizeof值)); } } //读取字符串值 string readString() { if(checkReadabilityStatus()) { char c; string result =; while((c = read< char>())!='\0') { result + = c; } return result; } return } //读取字符串值 void readString(string& result) { if(checkReadabilityStatus()) { char c; result =; while((c = read< char>())!='\0') { result + = c; } } }

您将使用它来WRITE:

string myPath =somepath to the file; BMBinaryIO binaryIO; if(binaryIO.open(myPath,BMBinaryIOMode :: Write)) { float value = 165; binaryIO.write(value); char valueC ='K' binaryIO.write(valueC); double valueD = 1231.99; binaryIO.write(valueD); string valueStr =spawnAt(100,200); binaryIO.writeString(valueStr); valueStr =helpAt(32,3); binaryIO.writeString(valueStr); binaryIO.close(); }

以下是如何使用它阅读:

string myPath =同一文件的某个路径; if(binaryIO.open(myPath,BMBinaryIOMode :: Read)) { cout< binaryIO.read< float>()<< endl; cout<< binaryIO.read< char>()<< endl; double valueD = 0; binaryIO.read(valueD); //或者你可以使用read< double() cout<< valueD<< endl; cout<< binaryIO.readString()<< endl; cout<< binaryIO.readString()<< endl; binaryIO.close(); }

编辑2:你甚至可以写/读整个结构1行:

struct Vertex { float x,y; }; 顶点vtx; vtx.x = 2.5f; vtx.y = 10.0f; //写它 binaryIO.write(vtx); //读取它 Vertex vtxRead; binaryIO.read(vtxRead); // option 1 vtxRead = binaryIO.read< Vertex>(); // option 2

希望我的代码足够清楚。

I'm looking for a way to write floats/ints/strings to a file and read them as floats/ints/strings. (basically read/write as ios::binary).

解决方案

I ended up writing it myself. Just wanted to share it with others.

It might not be optimized, but I had some difficulties finding C++ code that mimics C#'s BinaryReader & BinaryWriter classes. So I created one class that handles both read and write.

Quick things to note:

1) "BM" is just a prefix for my classes.

2) BMLogging is a helper class that simply does:

cout << "bla bla bla" << endl;

So you can ignore the calls to BMLogging, I kept them to highlight the cases where we could warn the user.

Here's the code:

#include <iostream> #include <fstream> using namespace std; // Create the macro so we don't repeat the code over and over again. #define BMBINARY_READ(reader,value) reader.read((char *)&value, sizeof(value)) enum BMBinaryIOMode { None = 0, Read, Write }; class BMBinaryIO { // the output file stream to write onto a file ofstream writer; // the input file stream to read from a file ifstream reader; // the filepath of the file we're working with string filePath; // the current active mode. BMBinaryIOMode currentMode; public: BMBinaryIO() { currentMode = BMBinaryIOMode::None; } // the destructor will be responsible for checking if we forgot to close // the file ~BMBinaryIO() { if(writer.is_open()) { BMLogging::error(BMLoggingClass::BinaryIO, "You forgot to call close() after finishing with the file! Closing it..."); writer.close(); } if(reader.is_open()) { BMLogging::error(BMLoggingClass::BinaryIO, "You forgot to call close() after finishing with the file! Closing it..."); reader.close(); } } // opens a file with either read or write mode. Returns whether // the open operation was successful bool open(string fileFullPath, BMBinaryIOMode mode) { filePath = fileFullPath; BMLogging::info(BMLoggingClass::BinaryIO, "Opening file: " + filePath); // Write mode if(mode == BMBinaryIOMode::Write) { currentMode = mode; // check if we had a previously opened file to close it if(writer.is_open()) writer.close(); writer.open(filePath, ios::binary); if(!writer.is_open()) { BMLogging::error(BMLoggingClass::BinaryIO, "Could not open file for write: " + filePath); currentMode = BMBinaryIOMode::None; } } // Read mode else if(mode == BMBinaryIOMode::Read) { currentMode = mode; // check if we had a previously opened file to close it if(reader.is_open()) reader.close(); reader.open(filePath, ios::binary); if(!reader.is_open()) { BMLogging::error(BMLoggingClass::BinaryIO, "Could not open file for read: " + filePath); currentMode = BMBinaryIOMode::None; } } // if the mode is still the NONE/initial one -> we failed return currentMode == BMBinaryIOMode::None ? false : true; } // closes the file void close() { if(currentMode == BMBinaryIOMode::Write) { writer.close(); } else if(currentMode == BMBinaryIOMode::Read) { reader.close(); } } bool checkWritabilityStatus() { if(currentMode != BMBinaryIOMode::Write) { BMLogging::error(BMLoggingClass::BinaryIO, "Trying to write with a non Writable mode!"); return false; } return true; } // Generic write method that will write any value to a file (except a string, // for strings use writeString instead). void write(void *value, size_t size) { if(!checkWritabilityStatus()) return; // write the value to the file. writer.write((const char *)value, size); } // Writes a string to the file void writeString(string str) { if(!checkWritabilityStatus()) return; // first add a \0 at the end of the string so we can detect // the end of string when reading it str += '\0'; // create char pointer from string. char* text = (char *)(str.c_str()); // find the length of the string. unsigned long size = str.size(); // write the whole string including the null. writer.write((const char *)text, size); } // helper to check if we're allowed to read bool checkReadabilityStatus() { if(currentMode != BMBinaryIOMode::Read) { BMLogging::error(BMLoggingClass::BinaryIO, "Trying to read with a non Readable mode!"); return false; } // check if we hit the end of the file. if(reader.eof()) { BMLogging::error(BMLoggingClass::BinaryIO, "Trying to read but reached the end of file!"); reader.close(); currentMode = BMBinaryIOMode::None; return false; } return true; } // reads a boolean value bool readBoolean() { if(checkReadabilityStatus()) { bool value = false; BMBINARY_READ(reader, value); return value; } return false; } // reads a character value char readChar() { if(checkReadabilityStatus()) { char value = 0; BMBINARY_READ(reader, value); return value; } return 0; } // read an integer value int readInt() { if(checkReadabilityStatus()) { int value = 0; BMBINARY_READ(reader, value); return value; } return 0; } // read a float value float readFloat() { if(checkReadabilityStatus()) { float value = 0; BMBINARY_READ(reader, value); return value; } return 0; } // read a double value double readDouble() { if(checkReadabilityStatus()) { double value = 0; BMBINARY_READ(reader, value); return value; } return 0; } // read a string value string readString() { if(checkReadabilityStatus()) { char c; string result = ""; while((c = readChar()) != '\0') { result += c; } return result; } return ""; } };

EDIT: I replaced all the read/write methods above with these: (updated the usage code as well)

// Generic write method that will write any value to a file (except a string, // for strings use writeString instead) template<typename T> void write(T &value) { if(!checkWritabilityStatus()) return; // write the value to the file. writer.write((const char *)&value, sizeof(value)); } // Writes a string to the file void writeString(string str) { if(!checkWritabilityStatus()) return; // first add a \0 at the end of the string so we can detect // the end of string when reading it str += '\0'; // create char pointer from string. char* text = (char *)(str.c_str()); // find the length of the string. unsigned long size = str.size(); // write the whole string including the null. writer.write((const char *)text, size); } // reads any type of value except strings. template<typename T> T read() { checkReadabilityStatus(); T value; reader.read((char *)&value, sizeof(value)); return value; } // reads any type of value except strings. template<typename T> void read(T &value) { if(checkReadabilityStatus()) { reader.read((char *)&value, sizeof(value)); } } // read a string value string readString() { if(checkReadabilityStatus()) { char c; string result = ""; while((c = read<char>()) != '\0') { result += c; } return result; } return ""; } // read a string value void readString(string &result) { if(checkReadabilityStatus()) { char c; result = ""; while((c = read<char>()) != '\0') { result += c; } } }

This is how you would use it to WRITE:

string myPath = "somepath to the file"; BMBinaryIO binaryIO; if(binaryIO.open(myPath, BMBinaryIOMode::Write)) { float value = 165; binaryIO.write(value); char valueC = 'K'; binaryIO.write(valueC); double valueD = 1231.99; binaryIO.write(valueD); string valueStr = "spawnAt(100,200)"; binaryIO.writeString(valueStr); valueStr = "helpAt(32,3)"; binaryIO.writeString(valueStr); binaryIO.close(); }

Here's how you would use it to READ:

string myPath = "some path to the same file"; if(binaryIO.open(myPath, BMBinaryIOMode::Read)) { cout << binaryIO.read<float>() << endl; cout << binaryIO.read<char>() << endl; double valueD = 0; binaryIO.read(valueD); // or you could use read<double() cout << valueD << endl; cout << binaryIO.readString() << endl; cout << binaryIO.readString() << endl; binaryIO.close(); }

EDIT 2: You could even write/read a whole structure in 1 line:

struct Vertex { float x, y; }; Vertex vtx; vtx.x = 2.5f; vtx.y = 10.0f; // to write it binaryIO.write(vtx); // to read it Vertex vtxRead; binaryIO.read(vtxRead); // option 1 vtxRead = binaryIO.read<Vertex>(); // option 2

Hope my code is clear enough.

更多推荐

我想在C ++中使用ifstream和stream的模仿C#的BinaryReader / BinaryWriter功能

本文发布于:2023-11-09 10:36:06,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1572154.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:我想   功能   ifstream   stream   BinaryReader

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!