Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C+中定义二进制文件的结构+;11_C++_C++11_Binaryfiles - Fatal编程技术网

C++ 在C+中定义二进制文件的结构+;11

C++ 在C+中定义二进制文件的结构+;11,c++,c++11,binaryfiles,C++,C++11,Binaryfiles,由于我必须大量使用二进制文件,我希望有一种更抽象的方法来实现这一点,我必须反复执行相同的循环: 写一个标题 按给定顺序编写不同类型的块(具有不同的值集) 编写可选的结束标头 现在我想用小的构建块来解决这个问题,想象一下,如果我可以写一些东西,比如XML的DTD,一个在给定块之后或在给定语义内部的定义,那么我可以用构建块来考虑我的文件,而不是十六进制值或类似的东西,此外,代码将更加“惯用”,而不那么晦涩 最后,语言中有什么东西可以帮助我从这个角度来研究二进制文件?< p>我不确定C++ 11的

由于我必须大量使用二进制文件,我希望有一种更抽象的方法来实现这一点,我必须反复执行相同的循环:

  • 写一个标题
  • 按给定顺序编写不同类型的块(具有不同的值集)
  • 编写可选的结束标头
现在我想用小的构建块来解决这个问题,想象一下,如果我可以写一些东西,比如XML的DTD,一个在给定块之后或在给定语义内部的定义,那么我可以用构建块来考虑我的文件,而不是十六进制值或类似的东西,此外,代码将更加“惯用”,而不那么晦涩


最后,语言中有什么东西可以帮助我从这个角度来研究二进制文件?

< p>我不确定C++ 11的特定特性,但是对于C++,流一般使文件I/O更容易处理。您可以重载stream insertion()操作符来实现您的目标。如果您不太熟悉运算符重载,请参阅的第9章,该章对其进行了很好的解释,并提供了许多示例。下面是在流上下文中重载>操作符的特殊方法

请允许我举例说明我的意思。假设我们定义了几个类:

  • BinaryFileStream—表示您尝试写入和(可能)读取的文件
  • BinaryFileStreamHeader-表示文件头
  • BinaryFileStreamChunk-表示一个块
  • BinaryFileStreamClosingHeader-表示结束标头
  • 然后,您可以在BinaryFileStream中重载流插入和提取操作符,以写入和读取文件(或任何其他istream或ostream)

    。。。
    #包括//I/O流定义,您可以为
    //ifstream和ofstream,但对istream和ostream这样做是错误的
    //更一般
    #包含//用于保存块
    类二进制文件流
    {
    公众:
    ...
    //写二进制流
    
    friend const std::ostream&Operator在该语言中?不。Boost序列化可能会帮助您,尽管它的序列化不是很容易移植。如果您非常聪明,您的流输入和流输出函数可以合并到一个函数中,并使用布尔标志来切换您是在读还是在写,因为大多数ime您的类的流输入和流输出函数无论如何都是相同的。我想如果语法不存在,它就不存在了,我试图用一些更抽象的东西来避免这种过程和编程风格。@JaminGrey您的意思是将int/bool的值模板化还是将if/else放在1个函数中?您可以d这样做,但是汇编中的每个“ReadFileFormatX”在每次读取时看起来都像是if()-elses()的大杂烩,速度会减慢。在我的代码中,我创建了一个用于读取的函数,一个用于在字节级别写入的函数(stream.ReadBytes(&data,size\t byteCount),stream.WriteBytes(&data,size\t byteCount))。然后我就有了“序列化”(stream,&i)”,它在内部调用stream.SerializeBytes(&i,sizeof(int)),如果“stream”设置为Read,SerializeBytes实际上是指向ReadBytes()的函数指针,如果设置为Write,它实际上是指向WriteBytes()的指针。然后我只专门化Serialize(stream,&type)对于更高级的类型,如std::string或自定义类。自定义类专门化只调用Serialize(stream,&myInt)和Serialize(stream,&myFloat)等。。。
    ...
    #include <iostream> // I/O stream definitions, you can specify your overloads for
                        // ifstream and ofstream, but doing so for istream and ostream is
                        // more general
    
    #include <vector>   // For holding the chunks
    
    class BinaryFileStream
    {
    public:
    ...
        // Write binary stream
        friend const std::ostream& operator<<( std::ostream& os, const BinaryFileStream& bfs )
        {
             // Write header
             os << bfs.mHeader;
    
             // write chunks
             std::vector<BinaryFileStreamChunk>::iterator it;
             for( it = bfs.mChunks.begin(); it != bfs.mChunks.end(); ++it )
             {
                 os << (*it);
             }
    
             // Write Closing Header
             os << bfs.mClosingHeader;
    
             return os;
        }
    ...
    private:
        BinaryFileStreamHeader             mHeader;
        std::vector<BinaryFileStreamChunk> mChunks;
        BinaryFileStreamClosingHeader      mClosingHeader;
    };