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

Writing C++ program compressing/decompressing data

本文关键字:解压缩 数据 压缩 C++ 程序 编写      更新时间:2023-10-16

我必须编写C++像gzip可以

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

gzip 文件
类型文件 |噗噗��

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

gzip -d 文件.gz
gzip -dc 文件.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

数据缓冲区.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

缓冲区编写器.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 或迭代器用文件或标准输入中的数据填充缓冲区。什么类来自标准或提升?什么参数?有些喜欢支持使用此功能定义类。

[编辑]:

#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

[编辑2]:

我想做与此线程相同的事情:从文件或标准读取,但以C++为单位。

通常,您从source读取输入并将其写入sink。最简单的情况是当你简单地写下你读到的内容时。但是,您希望对读取的数据应用transformation(或filter)。鉴于您正在追求"c ++方式",我建议您看看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,尽管它们确实抽象了很多,这使实现有些复杂。