gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 11:36:47 26 4
gpt4 key购买 nike

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

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

gzip file
type file | 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

数据缓冲区.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();
}

你能给我一些提示,告诉我如何改进输入和输出机制的代码吗?

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

[编辑]:

#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]:

我想做与此线程中相同的事情:Read from file or stdin , 但在 C++ 中。

最佳答案

通常,您从source 读取输入并将其写入sink。最简单的情况是您只写下您阅读的内容。但是,您想要对读取的数据应用转换(或过滤器)。鉴于您正在追求“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 的细节是无关紧要的——您可以读/写文件、网络适配器或其他任何东西,而无需任何结构更改.

要应用过滤器,我再次建议查看boost::iostreams,尽管它们抽象很多,这在某种程度上使实现变得复杂。 .

关于c++ - 编写 C++ 程序压缩/解压缩数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22781597/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com