1

所以,我正在编写 LZ77 压缩算法。以下是程序要求:

  • 程序应压缩任何未压缩的文件(.txt、.bmp 等)
  • 基于上述,程序应该使用二进制

现在事情开始对我来说有点不清楚,所以我需要一些建议。以下是我对这个问题的看法:

输入文件应以std::ios::binary. 下一个是什么?为方便起见,我认为将二进制作为字节使用是最佳的,对于我正在使用的字节解释chars(因为 1 char 等于 1 字节,如果我没记错的话)。因此我将文件数据作为字节(chars)读取到细绳。string现在我可以使用算法对这个字节进行编码。编码的输出是三元组向量. 现在我需要将此输出数据解释为字节以保存到压缩文件中,对吗?因为offsetlengthints,所以我需要将它们分成字节(chars)以将它们写入输出二进制流(因为ofstream::write争论是 char* 和要插入的字符数(字节))。nextchar可以按原样写。对于解码,我将步骤颠倒过来:从文件中读取三元组字节,然后使用算法进行解码。

我错过了一些重要的东西吗?在这种情况下使用字节是否正确?有什么错误的逻辑吗?下面是一些代码:

// Construct int from bytes
int intFromBytes(std::istream& is)
{
    char bytes[4];
    for (int i = 0; i < 4; ++i)
        is.get(bytes[i]);

    int integer;
    std::memcpy(&integer, &bytes, 4);
    return integer;
}

// Get bytes from int
void intToBytes(std::ostream& os, int value)
{
    char bytes[4];
    std::memcpy(&bytes, &value, 4);
    os.write(bytes, 4);
}

struct Node
{
    int offset, length;
    char next;
}

///// Packing /////

// Open and read binary data as a byte string
void readFileUnpacked(std::string& path) 
{
    std::ifstream file(path, std::ios::in | std::ios::binary);

    if (file.is_open())
    {

        Buffer = std::string(std::istreambuf_iterator<char>(file), {});
        file.close();
    }
}

///// Here should be the encoding logic /////

// Writing encoded triplets as bytes
void createFilePacked(std::string& path) 
{
    std::ofstream out(path, std::ios::out | std::ios::binary);

    if (out.is_open())
    {
        for (auto node : encoded)
        {
            intToBytes(out, node.offset);
            out << node.next;
            intToBytes(out, node.length);
        }
        out.close();
    }
}

///// Unacking /////

// Reading packed file as binary
readFilePacked(std::string& path)
{
    std::ifstream file(path, std::ios::in | std::ios::binary);

    if (file.is_open())
    {
        Node element;

        while (file.peek() != std::ifstream::traits_type::eof())
        {
            element.offset = intFromBytes(file);
            file.get(element.next);
            element.length = intFromBytes(file);
            encoded.push_back(element);
        }
        file.close();
    }
}

///// Here should be the decoding logic /////

createFileUnpacked(std::string& newpath) 
{
    std::ofstream out(newpath, std::ios::out | std::ios::binary);
    out << Buffer;
    out.close();
}
4

0 回答 0