zoukankan      html  css  js  c++  java
  • 自己做的一个输入输出缓冲池

    用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('');
    }
    
    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] != '')
        {
            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('	');
                }
        }
        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()) != '' && !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)
    



  • 相关阅读:
    一篇文章搞懂柏林噪声算法,附代码讲解
    画地为Mask,随心所欲的高效遮罩组件[Unity]
    丢掉Mask遮罩,更好的圆形Image组件[Unity]
    一个能下载到全网99%电子书的方法
    Unreal Engine 4 系列教程 Part 10:制作简单FPS游戏
    Unreal Engine 4 系列教程 Part 9:AI教程
    Unreal Engine 4 系列教程 Part 8:粒子系统教程
    Unreal Engine 4 系列教程 Part 7:音频教程
    Unreal Engine 4 系列教程 Part 6:动画教程
    Unreal Engine 4 系列教程 Part 5:制作简单游戏
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5134363.html
Copyright © 2011-2022 走看看