编写C ++程序压缩/解压缩数据

时间:2014-04-01 09:20:45

标签: c++ stream

我必须编写像gzip一样的C ++程序

*从文件或char流中获取输入,如下面的压缩

  

gzip文件
      类型文件| gzip的

*程序有文件或字符串流输出,如下面的解压缩

  

gzip -d file.gz
      gzip -dc file.gz

我不知道如何完成任务以及必须使用哪些技术以及如何创建缓冲输入和输出的类。我有类缓冲输入和输出以及从/到文件读/写数据。

DataBuffer.h(从文件中获取未压缩的数据):

#ifndef DataBuffer_h
#define DataBuffer_h

#include <fstream>
#include <string>

enum DataBufferState
{
  DATABUFFER_OK = 0,
  DATABUFFER_EOF = 1
};

class DataBuffer
{
    std::fstream file;
    std::string buffer;
  unsigned int maxBufferSize;
 public:
    DataBuffer(const std::string& filename, unsigned int maxBuffSize);
    ~DataBuffer();
    bool OpenFile(const std::string& filename);
    void SetMaxBufferSize(unsigned int maxBuffSize);
  DataBufferState FullBufferWithDataOld();
    DataBufferState FullBufferWithData();
    std::string GetDataBuffer();
};

#endif

DataBuffer.cpp:

#include "DataBuffer.h"

using namespace std;

DataBuffer::DataBuffer(const string& filename, unsigned int maxBuffSize)
{
    OpenFile(filename);
    SetMaxBufferSize(maxBuffSize);
}

DataBuffer::~DataBuffer()
{
  file.close();
}

bool DataBuffer::OpenFile(const string& filename)
{
    file.open(filename.c_str(),ios::in);
    if(!file.is_open())
    return false;
    return true;
}

void DataBuffer::SetMaxBufferSize(unsigned int maxBuffSize)
{
  maxBufferSize = maxBuffSize;
}

DataBufferState DataBuffer::FullBufferWithDataOld()
{
    while(true)
    {
        string line;
        streampos pos = file.tellg(); // Zapamietaj polozenie przed pobraniem linii
        getline(file,line);
        if( buffer.size()+line.size()>maxBufferSize )
        {
            // Cofnac wskaznik pliku
            file.seekg(pos,ios::beg); // Przywroc polozenie sprzed pobrania linii
            break;
        }
        buffer += line + "\n";
        if(file.eof())
      return DATABUFFER_EOF;
    }
    return DATABUFFER_OK;
}

DataBufferState DataBuffer::FullBufferWithData()
{
    char c;
  for(unsigned int i=0;i<maxBufferSize;++i)
    {
    c = file.get();
        if(file.eof()) break;
    buffer += c;
    }

    if(file.eof())
        return DATABUFFER_EOF;

    return DATABUFFER_OK;
}

string DataBuffer::GetDataBuffer()
{
    string buf = buffer;
    buffer.clear();
  return buf;
}

BufferWriter.h(将未压缩的数据保存到文件中):

#ifndef BufferWriter_h
#define BufferWriter_h

#include <string>
#include <fstream>

class BufferWriter
{
    std::string filename;
    std::fstream file;
 public:
     BufferWriter(const std::string& filename_);
    ~BufferWriter();
    bool OpenFile(const std::string& filename, bool appending);
    void SendBufferToFile(std::string& buffer);
};


#endif

BufferWriter.cpp

#include "BufferWriter.h"

using namespace std;

BufferWriter::BufferWriter(const string& filename_)
{
  filename = filename_;
    OpenFile(filename.c_str(),false);
    file.close();
}

BufferWriter::~BufferWriter()
{
  file.close();
}

bool BufferWriter::OpenFile(const string& filename, bool appending)
{
    if(appending)
        file.open(filename.c_str(),ios::out | ios::app);
    else
    file.open(filename.c_str(),ios::out);
    if(!file.is_open())
        return false;
    return true;
}

void BufferWriter::SendBufferToFile(string& buffer)
{
  OpenFile(filename,true);
    file.write(buffer.c_str(),buffer.size());
    file.close();
}

您能否给我一些提示,以改进输入和输出机制的代码?

假设我有下面的类,如何使用istream或迭代器来填充来自文件或标准输入的数据的缓冲区。什么类来自std或boost?什么参数?有些人喜欢用这个功能来支持类的定义。

[编辑]:

#ifndef StreamBuffer_h
#define StreamBuffer_h

#include <string>

using namespace std;

enum DataBufferState
{
  DATABUFFER_OK = 0,
  DATABUFFER_EOF = 1
};

// gzip plik
// type plik | gzip -d
// gzip -d plik.gz
// gzip -dc plik.gz 

// Parametr konstruktora to strumien z ktorego chcemy czytac i dlugosc bufora
class StreamBuffer
{
    int maxBufferSize;
    std::string buffer;
    StreamBuffer(int maxBuffSize)
    {
    SetMaxBufferSize(maxBuffSize);
    }
    ~StreamBuffer()
    {
    }
    void SetMaxBufferSize(unsigned int maxBuffSize)
    {
    maxBufferSize = maxBuffSize;
    }
    DataBufferState FullBufferWithData()
    {
      // What to use what to do in this method to read part of file or standard char input to buffer?
    }
    std::string GetDataBuffer()
    {
    return buffer;
    }
};

#endif

[EDIT2]:

我想在这个帖子中做同样的事情:Read from file or stdin,但是在C ++中。

1 个答案:

答案 0 :(得分:1)

通常,您从source读取输入并将其写入sink。最简单的情况是当你简单地写下你所读的内容时。但是,您希望将transformation(或filter)应用于您阅读的数据。在c ++方式&#34;&#34; c ++方式之后看,&#34;我建议您查看boost::iostreams,其中sources / sinks对任务进行抽象。

Boost通过以下方式定义抽象来源:

struct Source {
    typedef char        char_type;
    typedef source_tag  category;
    std::streamsize read(char* s, std::streamsize n) 
    {
        // Read up to n characters from the input 
        // sequence into the buffer s, returning   
        // the number of characters read, or -1 
        // to indicate end-of-sequence.
    }
};

sinks以类似的方式定义(当然,使用write代替read。这样做的好处是source / sink的详细信息无关紧要 - 您可以读取/写入文件,网络适配器或其他任何内容,而无需进行任何结构更改。

要应用filters,我再次建议查看boost::iostreams,虽然它们会抽象抽象,这会使实现变得复杂。