用C++做的一个输入输出缓冲池,可优化硬盘文件读写的速度,支持多种数据类型。
// buffer.h
// Buffer classes can make input and output faster.
#ifndef BUFFER_H
#define BUFFER_H
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
class OBuffer
{
unsigned char* storage;
int location;
std::ofstream out;
int bufsize;
bool bin; //1-bin-output 0-text-output
public:
void close()
{
flush();
out.close();
}
OBuffer(const std::string filename, bool b = true, int size = 1024);
~OBuffer()
{
close();
delete[] storage;
}
void write(const std::string& var);
void write(const long var);
void write(const double var);
void write(const bool var);
void write(const char var);
void write(const int var);
void write(const char* var);
void write(const std::vector<std::string>& var);
void write(const std::vector<long>& var);
void write(const std::vector<double>& var);
void write(const std::vector<bool>& var);
void write(const std::vector<char>& var);
void write(const std::vector<int>& var);
private:
void flush();
public:
OBuffer& operator << (const std::string& var);
OBuffer& operator << (const long var);
OBuffer& operator << (const double var);
OBuffer& operator << (const bool var);
OBuffer& operator << (const char var);
OBuffer& operator << (const int var);
OBuffer& operator << (const char* var);
OBuffer& operator << (const std::vector<std::string>& var);
OBuffer& operator << (const std::vector<long>& var);
OBuffer& operator << (const std::vector<double>& var);
OBuffer& operator << (const std::vector<bool>& var);
OBuffer& operator << (const std::vector<char>& var);
OBuffer& operator << (const std::vector<int>& var);
};
class IBuffer
{
unsigned char* storage;
int location;
std::ifstream in;
int bufsize;
bool bin;
bool isEOF;
int filesize;
// in normal case, the input file isn't end
// so the end is a location that can't reach
// when the file is end,
// the end is set a number that when
// location reach it, the buffer is end;
int end;
bool hasTemp;
char tempChar;
public:
IBuffer(const std::string filename, bool b = true, int size = 1024);
void close()
{
in.close();
flush();
}
~IBuffer()
{
close();
delete[] storage;
}
bool eof()
{
return isEOF;
}
private:
void flush()
{
location = -1;
in.read((char*)storage, bufsize);
if (in.eof())
end = filesize % bufsize - 1;
if (end == -1)
end = bufsize - 1;
}
char get();
public:
void read(int& var);
void read(long& var);
void read(std::string& var);
void read(double& var);
void read(char& var);
void read(bool& var);
void read(std::vector<int>& var, int length);
void read(std::vector<long>& var, int length);
void read(std::vector<double>& var, int length);
void read(std::vector<std::string>& var, int length);
void read(std::vector<char>& var, int length);
void read(std::vector<bool>& var, int length);
IBuffer& operator >> (std::string& var);
IBuffer& operator >> (long& var);
IBuffer& operator >> (double& var);
IBuffer& operator >> (bool& var);
IBuffer& operator >> (char& var);
IBuffer& operator >> (int& var);
};
#endif
// buffer.cc
// implement of the buffer.h
#include "buffer.h"
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <ctype.h>
using namespace std;
/*****************************OBuffer***********************/
OBuffer::OBuffer(const string filename, bool b, int size) :
bufsize(size), location(-1), bin(b)
{
if (size <= 0)
{
cerr << "The size of buffer error!" << endl;
exit(EXIT_FAILURE);
}
if (bin)
out.open(filename.c_str(), fstream::binary);
else
out.open(filename.c_str());
storage = new unsigned char[bufsize];
if (storage == NULL)
{
cerr << "Memory error!" << endl;
exit(EXIT_FAILURE);
}
}
void OBuffer::flush()
{
if (location < 0)
return;
/*for (int i = 0; i <= location; i++)
{
out << storage[i];
}*/
out.write((char*)storage, location + 1);
location = -1;
}
void OBuffer::write(const char var)
{
storage[++location] = (unsigned char)var;
if (location >= bufsize - 1)
flush();
}
void OBuffer::write(const string& var)
{
for (int i = 0; i < var.length(); i++)
write(var[i]);
if (bin)
write('\0');
}
OBuffer& OBuffer::operator << (const char var)
{
write(var);
return *this;
}
OBuffer& OBuffer::operator << (const string& var)
{
write(var);
return *this;
}
#define WRITE(ArgT) \
void OBuffer::write(const ArgT var) {\
if (bin) {\
for (int i = 0; i < sizeof(ArgT); i++)\
write(((char*)(&var))[i]);\
} else {\
ostringstream oss;\
oss << var;\
string temp = oss.str();\
write(temp);\
}\
}\
OBuffer& OBuffer::operator << (const ArgT var) {\
write(var);\
return *this;\
}
WRITE(long)
WRITE(double)
WRITE(int)
void OBuffer::write(const bool var)
{
if (bin) {
for (int i = 0; i < sizeof(bool); i++)
write(((char*)(&var))[i]);
} else {
if (var)
write('1');
else
write('0');
}
}
OBuffer& OBuffer::operator << (const bool var)
{
write(var);
return *this;
}
void OBuffer::write(const char* var)
{
char c;
int i = 0;
while (var[i] != '\0')
{
write(var[i]);
i++;
}
}
OBuffer& OBuffer::operator << (const char* var)
{
write(var);
return *this;
}
#define VWRITE(ArgT) \
void OBuffer::write(const vector<ArgT>& var) {\
if (bin) \
for (int i = 0; i < var.size(); i++) \
write(var[i]);\
else\
for (int i = 0; i < var.size(); i++) {\
write(var[i]);\
write('\t');\
}\
}\
OBuffer& OBuffer::operator << (const vector<ArgT>& var) {\
write(var);\
return *this;\
}
VWRITE(string)
VWRITE(long)
VWRITE(double)
VWRITE(bool)
VWRITE(char)
VWRITE(int)
/*************************IBuffer************************/
IBuffer::IBuffer(const string filename, bool b, int size) :
bin(b), bufsize(size), isEOF(false), location(-1),
hasTemp(false)
{
if (size <= 0)
{
cerr << "The size of buffer error!" << endl;
exit(EXIT_FAILURE);
}
if (bin)
in.open(filename.c_str(), ios::binary);
else
in.open(filename.c_str());
in.seekg(0, ios::end);
filesize = in.tellg();
in.seekg(0, ios::beg);
storage = new unsigned char[bufsize];
if (storage == NULL)
{
cerr << "Memory error!" << endl;
exit(EXIT_FAILURE);
}
end = size + 1;
flush();
}
char IBuffer::get()
{
if (location > end)
{
cerr << "Input out of range." << endl;
exit(EXIT_FAILURE);
}
char c;
if (!hasTemp){
location++;
c = storage[location];
if (location == end)
isEOF = true;
if (location >= bufsize - 1)
flush();
}
else
{
c = tempChar;
hasTemp = false;
}
return c;
}
void IBuffer::read(char& var)
{
if (isEOF)
return;
var = get();
}
#define READ(ArgT) \
void IBuffer::read(ArgT& var) {\
if (bin)\
for (int i = 0; i < sizeof(ArgT); i++)\
((char*)&var)[i] = get();\
else {\
string temp;\
temp.clear();\
char c;\
while (isdigit(c = get()))\
temp.append(1, c);\
hasTemp = true;\
tempChar = c;\
istringstream scan(temp);\
scan >> var;\
}\
}\
IBuffer& IBuffer::operator >> (ArgT& var) {\
read(var);\
return *this;\
}
READ(int)
READ(long)
void IBuffer::read(double& var)
{
if (bin)
for (int i = 0; i < sizeof(double); i++)
((char*)&var)[i] = get();
else {
string temp;
temp.clear();
char c = get();
while (isdigit(c) || c == '.')
{
temp.append(1, c);
c = get();
}
hasTemp = true;
tempChar = c;
istringstream scan(temp);
scan >> var;
}
}
IBuffer& IBuffer::operator >> (double& var) {
read(var);
return *this;
}
void IBuffer::read(bool& var)
{
if (bin)
for (int i = 0; i < sizeof(bool); i++)
((char*)&var)[i] = get();
else {
char c = get();
if (c == '0')
var = false;
else if (c == '1')
var = true;
else
cerr << "Not a bool!" << endl;
}
}
IBuffer& IBuffer::operator >> (bool& var) {
read(var);
return *this;
}
void IBuffer::read(string& var)
{
var.clear();
char c;
if (bin)
while ((c = get()) != '\0' && !isEOF)
var.append(1, c);
else
while (!isspace(c = get()) && !isEOF)
var.append(1, c);
}
IBuffer& IBuffer::operator >> (string& var)
{
read(var);
return *this;
}
#define VREAD(ArgT) \
void IBuffer::read(vector<ArgT>& var, int length) {\
ArgT v;\
for (int i = 0; i < length; i++) {\
read(v);\
var.push_back(v);\
}\
}
VREAD(string)
VREAD(long)
VREAD(int)
VREAD(double)
VREAD(char)
VREAD(bool)