Skip to content

Instantly share code, notes, and snippets.

@lixingcong
Last active September 5, 2017 10:50
Show Gist options
  • Select an option

  • Save lixingcong/5c8c85d2e6bf3524505c696d3fe3f774 to your computer and use it in GitHub Desktop.

Select an option

Save lixingcong/5c8c85d2e6bf3524505c696d3fe3f774 to your computer and use it in GitHub Desktop.
file_read_and_write读取保存
#include <iostream>
#include "FileReadWrite.h"
using namespace std;
#define BUF_SIZE 3000
int main() {
char test_chars[BUF_SIZE]={0};
for(int i=0;i<9;i++)
test_chars[i]='0'+i;
char test_string[BUF_SIZE]="fuck";
std::string filename="test1.bin";
FileReadWrite frw(filename);
std::cout<<"sizeof(test_chars)="<<sizeof(test_chars)<<endl;
frw.push_element_soft(sizeof(test_string),test_string);
frw.push_element_soft(sizeof(test_chars),test_chars);
frw.push_element_hard(sizeof(test_chars),test_chars);
for(int i=0;i<9;i++)
test_chars[i]='a'+i;
frw.write();
frw.read();
char got_0[BUF_SIZE],got_1[BUF_SIZE],got_2[BUF_SIZE];
int size_0,size_1,size_2;
frw.get_element(0,&size_0,got_0);
frw.get_element(1,&size_1,got_1);
frw.get_element(2,&size_2,got_2);
cout<<"soft, size="<<size_0<<", data="<<got_0<<endl;
cout<<"soft, size="<<size_1<<", data="<<got_1<<endl;
cout<<"hard, size="<<size_2<<", data="<<got_2<<endl;
return 0;
}
/*
* FileReadWrite.cpp
*
* Created on: 2017年7月28日上午11:10:36
* Author: lixingcong
*/
#include "FileReadWrite.h"
#include <iostream>
FileReadWrite::FileReadWrite(std::string filename) {
_filename=filename;
_buffer_raw=NULL;
}
void FileReadWrite::setFileName(std::string filename) {
_filename=filename;
}
int FileReadWrite::read_raw() {
int filesize=get_filesize();
if(filesize<0)
return -1;
std::ifstream ifs(_filename.c_str(), std::ios::in | std::ios::binary);
if (!ifs.is_open()) {
std::cerr << "read error: open file failed!\n";
abort();
}else{
// allocate the buffer
_buffer_raw=new unsigned char [filesize];
ifs.read((char*)_buffer_raw,filesize);
ifs.close();
}
return filesize;
}
/*
* brief: 从文件名filename中读取全部内容
* param: void
* return: filename的文件大小
*/
int FileReadWrite::read() {
int offset=0;
int filesize;
clear(); // remove all elements and delete _buffer_raw
filesize=read_raw();
if(filesize<0)
return -1;
unsigned char* ptr_buffer=_buffer_raw;
data_block_t data_block;
while(ptr_buffer+offset<_buffer_raw+filesize){
data_block.size=*((int*)(ptr_buffer+offset));
data_block.ptr_data=ptr_buffer+offset+sizeof(int);
offset+=(data_block.size+sizeof(int));
_data.push_back(data_block);
}
return filesize;
}
/*
* brief: 把vector数组写入到文件名filename中
* param: void
* return: 成功写入的数据尺寸
*/
int FileReadWrite::write() {
int filesize=0;
std::vector<data_block_t>::iterator it;
if(_data.empty()==true)
return -1;
if(_buffer_raw!=NULL){
delete []_buffer_raw;
_buffer_raw=NULL;
}
// 计算待写入的二进制文件大小
for(it=_data.begin();it!=_data.end();++it){
filesize+=sizeof(int);
filesize+=(*it).size;
}
_buffer_raw=new unsigned char [filesize];
unsigned char* ptr_buffer=_buffer_raw;
// 覆盖buffer
for(it=_data.begin();it!=_data.end();++it){
memcpy(ptr_buffer,&(*it).size,sizeof(int));
ptr_buffer+=sizeof(int);
memcpy(ptr_buffer,(*it).ptr_data,(*it).size);
ptr_buffer+=(*it).size;
}
return write_raw(filesize);
}
FileReadWrite::~FileReadWrite() {
clear();
}
/*
* brief: 从vector中获取一个下标index的元素大小
* param: index 下标
* size 指针,指向数据的尺寸
* return: 成功返回0,不存在元素返回-1
*/
int FileReadWrite::get_element_size(unsigned int index, int* size){
if(index>=_data.size())
return -1;
*size=_data[index].size;
return 0;
}
/*
* brief: 从vector中获取一个下标index的元素
* param: index 下标
* size 指针,指向数据的尺寸
* data 指针,指向任意数据
* return: 成功返回0,不存在元素返回-1
*/
int FileReadWrite::get_element(unsigned int index, int* size, void* data) {
if(index>=_data.size())
return -1;
*size=_data[index].size;
memcpy(data,_data[index].ptr_data,_data[index].size);
return 0;
}
int FileReadWrite::write_raw(int filesize) {
std::ofstream ofs(_filename.c_str(), std::ios::out | std::ios::binary | std::ios::trunc);
if (!ofs.is_open()) {
std::cerr << "write error: open file failed!\n";
abort();
}else{
ofs.write((char*)_buffer_raw,filesize);
ofs.close();
}
return get_filesize();
}
int FileReadWrite::get_filesize() {
std::ifstream ssin(_filename.c_str(), std::ios::ate | std::ios::binary);
return (int)(ssin.tellg());
}
/*
* brief: 把元素放入vector中,使用指针方式链接到data数据,不进行硬拷贝
* param: size 指向数据的尺寸
* data 任意数据
* return: vector数组index
*/
int FileReadWrite::push_element_soft(int size, void* data) {
data_block_t data_block;
data_block.size=size;
data_block.is_soft_link=true;
data_block.ptr_data=(unsigned char*)data;
_data.push_back(data_block);
return _data.size()-1;
}
/*
* brief: 把元素放入vector中,使用memcpy方式拷贝data数据到vector中
* param: size 指向数据的尺寸
* data 任意数据
* return: vector数组index
*/
int FileReadWrite::push_element_hard(int size, void* data) {
data_block_t data_block;
data_block.size=size;
data_block.is_soft_link=false;
data_block.ptr_data=new unsigned char [size];
memcpy(data_block.ptr_data,data,size);
_data.push_back(data_block);
return _data.size()-1;
}
/*
* brief: 清除所有动态申请的空间,包括read-buffer和vector数组
* param: void
* return: void
*/
void FileReadWrite::clear(){
if(_buffer_raw!=NULL){
delete []_buffer_raw;
_buffer_raw=NULL;
}
if(false==_data.empty()){
for(std::vector<data_block_t>::iterator it=_data.begin();it!=_data.end();++it){
if(false==(*it).is_soft_link){
delete [] (unsigned char*)(*it).ptr_data;
}
}
_data.clear();
}
}
/*
* FileReadWrite.h
*
* Created on: 2017年7月28日上午11:10:36
* Author: lixingcong
*/
#ifndef FILEREADWRITE_H_
#define FILEREADWRITE_H_
#include <string>
#include <vector>
#include <fstream>
typedef struct {
int size; // 数据长度
bool is_soft_link; // 是否软连接,如果是,下面的指针指向data,如果否,则指针动态申请内存
unsigned char* ptr_data; // 数据块,当hard-link时候动态申请内存
}data_block_t;
class FileReadWrite {
public:
FileReadWrite(std::string filename);
~FileReadWrite();
void setFileName(std::string filename);
int read(); // 读取filename到vector数组
int write(); // 把vector内容写入到filename
int push_element_soft(int size, void* data); // 添加一个大小size的数据到vector数组
int push_element_hard(int size, void* data); // 添加一个大小size的数据到vector数组
int get_element_size(unsigned int index, int* size); // 从vector数组中获得下标为index的元素的大小
int get_element(unsigned int index, int* size, void* data); // 从vector数组中获得下标为index的元素
void clear(); // 清除所有动态申请的空间,包括read-buffer和vector数组
private:
int get_filesize(); // filename读取文件大小
int read_raw(); // 底层的读取到buffer_raw
int write_raw(int filesize); // 底层写入到buffer_raw
std::string _filename;
std::vector<data_block_t> _data;
unsigned char* _buffer_raw;
};
#endif /* FILEREADWRITE_H_ */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment