自己做的一个输入输出缓冲池

用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)



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值