为了方便开发,写了一个文本读写程序,能够读写二进制/文本格式的文件,程序只由一个头文件组成,可以很方便地加入到现有程序。完整程序如下:
#ifndef FILE_HELPER_HPP
#define FILE_HELPER_HPP
#include
#include
// FileWriter //
class FileWriter{
public:
FileWriter(const std::string& file_name){
file_.open(file_name, std::ios::out);
}
~FileWriter(){
file_.close();
}
void write_txt(const std::string& str){
file_ << str;
}
void write_bin(const char* bytes, size_t size){
file_.write(bytes, size);
}
void close(){
file_.close();
}
static std::shared_ptr<FileWriter> create(const std::string& file_name){
return std::make_shared<FileWriter>(file_name);
}
private:
std::ofstream file_;
};
using FileWriterPtr = std::shared_ptr<FileWriter>;
// FileReader //
class FileReader{
public:
enum{
TXT = 0,
BIN,
};
public:
FileReader(const std::string& file_name, int type){
if(type == BIN)
file_.open(file_name, std::ios::binary);
else
file_.open(file_name, std::ios::in);
}
~FileReader(){
file_.close();
}
void read_txt(double* buf, size_t size){
for(size_t i = 0; i < size; ++i){
file_ >> buf[i];
}
}
char* read_bin(size_t size){
auto bytes = new char[size];
file_.read(bytes, size);
return bytes;
}
void close(){
file_.close();
}
static std::shared_ptr<FileReader> create(const std::string& file_name, int type = TXT){
return std::make_shared<FileReader>(file_name, type);
}
private:
std::ifstream file_;
};
using FileReaderPtr = std::shared_ptr<FileReader>;
#endif // FILE_HELPER_HPP
使用流程大致为:
to_string()
方法。实例化一个数据结构体测试程序如下:
#include
#include "file_helper.hpp"
struct Data{
double x;
double y;
double z;
inline std::string to_string(){
return std::to_string(x) + " " + std::to_string(y) + " " + std::to_string(z) + "\n";
}
};
int main(int argc, char** argv){
Data data{1.0, 2.0, 3.0};
/// Text ///
FileWriterPtr writer_txt = FileWriter::create("test.txt");
writer_txt->write_txt(data.to_string());
writer_txt->close();
FileReaderPtr reader_txt = FileReader::create("test.txt");
Data data_txt;
reader_txt->read_txt((double*)(&data_txt), sizeof(Data) / sizeof(double));
std::cout << "文本文件读取结果 : " << std::endl;
std::cout << data_txt.to_string() << std::endl;
/// Binary ///
FileWriterPtr writer_bin = FileWriter::create("test.bin");
writer_bin->write_bin((char*)(&data), sizeof(Data));
writer_bin->close();
FileReaderPtr reader_bin = FileReader::create("test.bin");
Data data_bin;
reader_bin->read_bin((char*)(&data_bin), sizeof(Data));
std::cout << "二进制文件读取结果: " << std::endl;
std::cout << data_bin.to_string() << std::endl;
return 0;
}
测试结果:
文本文件读取结果 :
1.000000 2.000000 3.000000
二进制文件读取结果:
1.000000 2.000000 3.000000
在Data
结构体中实现to_string()
方法,还可以使用以下两种方式
#include
inline std::string to_string() const{
std::stringstream ss;
ss.precision(15); // 设置保存位数
ss << x << " " << y << " " << z
<< std::endl;
return ss.str();
}
inline std::string to_string() const{
return fmt::format("{} {} {}\n", x, y, z);
}
注:需要另外安装fmt
Python文件读写非常方便,使用Numpy即可
import numpy as np
data = np.array([[0.1, 1, 2.2],
[3.3, 4, 5.2],
[6.7, 7, 8.9]])
##### 文本文件操作 #####
# 保存为txt
np.savetxt("data.txt", data)
# 定义数据格式 i1: int8 i2: int16 f4: float64
data_type = np.dtype([("a", "i1"), ("b", "f4"), ("c", "f8")])
# 按照指定格式导入txt文件
data = np.loadtxt("data.txt", dtype=data_type)
# 访问读取的结果
print(data['a'])
print(data['b'])
print(data['c'])
##### 二进制文件操作 #####
# 保存为bin
data.tofile("data.bin")
# 按照指定格式导入bin文件
data = np.fromfile("data.bin", dtype=data_type)
# 访问读取的结果
print(data['a'])
print(data['b'])
print(data['c'])
运行结果:
----- txt -----
[0 3 6]
[1. 4. 7.]
[2.2 5.2 8.9]
----- bin -----
[0 3 6]
[1. 4. 7.]
[2.2 5.2 8.9]