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

简介:

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








本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5134363.html,如需转载请自行联系原作者

相关文章
|
机器学习/深度学习 存储 缓存
输入输出大全(普通输入输出和快读快写)C/C++
输入输出大全(普通输入输出和快读快写)C/C++
339 0
|
6月前
|
存储 缓存 数据处理
计算机硬件存储器中的缓冲与缓存
【8月更文挑战第2天】
368 5
|
8月前
|
存储 Java 中间件
详尽分享缓冲区(Buffer)
详尽分享缓冲区(Buffer)
104 0
|
9月前
|
存储 缓存
怎么理解内存中的Buffer和Cache?
怎么理解内存中的Buffer和Cache?
92 2
|
C++
C++文件的随机读写与特定格式输入输出
C++文件的随机读写与特定格式输入输出
86 0
|
存储 缓存 数据处理
缓存与缓冲区的区别
在计算机科学中,缓存(Cache)和缓冲区(Buffer)是两个常见的概念。尽管它们的功能有些相似,但它们在实际应用中具有不同的用途和工作原理。本文将介绍缓存和缓冲区之间的区别。
688 0
【PE准备阶段】将内存中的数据读取到内存,将内存中的数据读取到文件中【滴水逆向39期作业】
【PE准备阶段】将内存中的数据读取到内存,将内存中的数据读取到文件中【滴水逆向39期作业】
|
存储 缓存 Linux
C输入输出缓存
C输入输出缓存
163 0
C输入输出缓存
|
存储 索引
LotusDB 设计与实现—3 内存 memtable
顾名思义,memtable 是内存中维护的组件,在 LSM Tree 存储模型中,memtable 相当于一块内存 buffer,数据写入到 WAL 后,然后在 memtable 中更新。memtable 的数据积累到一定的阈值之后,批量 Flush 到磁盘,这样做的目的是延迟写磁盘,并且将随机的 IO 写入转换为批量的顺序 IO,这也是 LSM 存储模型的核心思路。
183 0
IO流的字节流的缓冲和非缓冲方式的区别及性能对比
IO流的字节流的缓冲和非缓冲方式的区别及性能对比
281 0