【问题标题】:Best Binary reader for C++?C++ 的最佳二进制阅读器?
【发布时间】:2015-03-14 13:31:06
【问题描述】:

我在互联网上寻找读取二进制文件的最佳方法,它们都导致 ifstream 或 istream。

我并不是说他们不好,但我无法相处。很多,因为我只能读数字。

我正在 C++ 中寻找与 C# 的 BinaryReader 等效的东西,即使它更难,我也想在任何地方找到一些指导方针,我只能找到阅读完整文件缓冲区的人的指导,而没有其他

我尝试使用 C# 中的 System::IO 二进制阅读器,但由于我使用互斥锁,我无法使用该选项。

这是我阅读这些内容的方式。

std::ifstream f(filename, std::ios::binary); //Open the file

f.read((char*)&header, sizeof(4)); //ReadInt32

SCNObject obj(f);

构造函数:

SCNObject::SCNObject(std::ifstream& f)
{
    f.read((char*)&ID, sizeof(4));
    name = (ReadString(f));
    parentName = (ReadString(f));
}

我的 ReadString 函数:

std::string ReadNTString(std::ifstream& file)
{
    char ch = 0;
    std::string str = "";
    while (ch != '\0')
    {
        ch = file.get();
        str += ch;
    }
    return str;
}

此时我以为我会得到我想要的东西,但我只是得到了字符串上的数字。 日志:

Name: 1288880
Parent Name: 1288880

而且他们根本没有同名,所以我现在很困惑,我不想想象当我尝试阅读花车时我将如何做到这一点。

我知道这不是这样做的方法,我敢打赌有更好的方法,但我只是在互联网上找不到它,是一遍又一遍的相同教程,我没有'不知道怎么做,或者我做得不对,单独学习 c++ 很难......

如果有人能给我一些关于如何学习解析基本数据(例如浮点数、以空结尾的字符串)的指导,并且如果有更好的读取整数的方法,我将不胜感激,我是好迷茫,我不知道该怎么办。

提前非常感谢

【问题讨论】:

  • 仅供参考,sizeof(4) ?你是打算读取一个有保证的 4 个字节,还是整数常量 4 被用来以某种方式发送 sizeof(int)(它实际上在做什么)?
  • 通常的模式是f.read(reinterpret_cast<char*>(&header), sizeof header);。丑陋的语法使您设计抽搐,因为这不一定是可移植的。我喜欢定义一个read 函数,SFINAE 使用std::is_trivial(或std::is_trivially_copyable,如果你的库支持它)来确保我不会将它用于非平凡的类。
  • 4 是为了确保我正在读取 4 个字节,但我从未想过使用 int 的大小来代替,谢谢 :P 是的,我的库支持它,我可以查看并使用它!
  • @SeyrenWindsor 从您的回复来看,我认为您不理解我的评论。 sizeof(4) sizeof(int),因为4 就是这样;一个int。如果您想准确地阅读 4 个八位字节,那么这就是您传递的内容:4。在这种情况下没有sizeof。如果这是一个可能被多个平台读写的固定格式文件,sizeof(int)不是无论如何你都应该使用的。
  • 哦,那我看错了,不好意思,我理解错了,那我的做法是对的,如你所说,这是一个固定格式的文件,会被读取在 3D 引擎中,我已经用 C# 对其进行了编码,但我有兴趣学习这种语言 + 3ds max 仅在其插件中使用 C++。

标签: c++ parsing binary 3dsmax


【解决方案1】:

可以使用boost的序列化库

http://www.boost.org/doc/libs/1_57_0/libs/serialization/doc/index.html

它支持 c++ 原语和 STL 容器的二进制序列化,并提供一个框架来将序列化扩展到您自己的类型。 (但请记住,它不能跨不同的机器架构移植)

下面是简单字符串和浮点数的序列化。

//writer.cpp
#include <boost/serialization/string.hpp>                                                       
#include <boost/archive/binary_oarchive.hpp>                                                    
#include <fstream>                                                                              

int main() {                                                                                    
  std::ofstream out("mydata.bin");                                                              
  boost::archive::binary_oarchive oarchive(out);                                                
  std::string s = "abc";                                                                        
  float x = 123.0f;                                                                             
  oarchive << s << x;                                                                           
  return 0;                                                                                     
} 

//reader.cpp
#include <boost/serialization/string.hpp>                                                       
#include <boost/archive/binary_iarchive.hpp>                                                    
#include <fstream>                                                                              

int main() {                                                                                    
  std::ifstream in("mydata.bin");                                                               
  boost::archive::binary_iarchive iarchive(in);                                                 
  std::string s;                                                                                
  float x;                                                                                      
  iarchive >> s >> x;                                                                           
  std::cout << s << x << '\n';                                                                  
  return 0;                                                                                     
}  

【讨论】:

  • 我阅读代码的方式似乎正是我需要的浮点数和字符串!,我会尝试一下,我会告诉你的!
  • 放入后出现很多错误和异常,特别是语法可能是我的错,我今天不能继续,明天我让你,但似乎这可能是我正在寻找的东西,非常感谢!
【解决方案2】:

您可以使用std::getline 读取std::string。您可以指定字符串结尾字符或使用默认换行符。

从文件中读取的最佳方法是读取大块,然后从内存中操作这些块。这减少了对输入流的请求数量。

【讨论】:

    猜你喜欢
    • 2012-01-27
    • 1970-01-01
    • 1970-01-01
    • 2012-03-27
    • 2014-11-17
    • 1970-01-01
    • 1970-01-01
    • 2010-10-14
    • 1970-01-01
    相关资源
    最近更新 更多