【问题标题】:Finding specific primitives within a binary file在二进制文件中查找特定原语
【发布时间】:2013-03-28 21:32:12
【问题描述】:

有没有办法在二进制文件中找到特定的原语(例如 MATLAB 中的 fread 或 Mathematica 中的 BinaryReadLists)?具体来说,我想扫描我的文件,直到它达到一个 int8_t 精度数,然后将其存储在一个变量中,然后扫描另一个原语(无符号字符、双精度等)?

我正在从 MATLAB 重写执行此操作的代码,因此文件的格式是已知的。

我想读取文件中仅指定类型(32 位 int、char、..)的 n 个字节。例如:如果返回为 8 位整数,则只读取文件的前 12 个字节

【问题讨论】:

  • 不。如果你有一个二进制文件但不知道内容的格式,那么就不可能知道任何东西的类型是什么。 int 和 float 和 char* 无法区分。
  • 谢谢。我应该提到,但我知道格式。我正在从 MATLAB 重写代码。
  • 如果你知道格式然后.....我完全不明白你的问题。如果您知道格式,为什么要“扫描直到找到 int8_t”?只需告诉我们您想做什么,而且很容易。
  • 我想读取文件中指定类型(32 位 int、char、..)的 n 个字节。例如:如果返回为 8 位整数,则只读取文件的前 12 个字节

标签: c++ file binary primitive-types


【解决方案1】:

也许解决您的问题的方法是了解这两个文档页面之间的区别:

http://www.mathworks.com/help/matlab/ref/fread.html http://www.cplusplus.com/reference/cstdio/fread/

两个版本的 fread 都允许您从二进制文件中拉入一组项目。我从你的问题中假设你知道你需要的数组的大小和形状。

#include <stdio.h>

int main() {
  const size_t NumElements = 128; // hopefully you know
  int8_t myElements[NumElements];
  FILE *fp = fopen("mydata.bin", "rb");
  assert(fp != NULL);
  size_t countRead = fread(myElements, sizeof(int8_t), NumElements, fp);
  assert(countRead = NumElements);

  // do something with myElements
}

【讨论】:

    【解决方案2】:

    你的问题对我来说毫无意义,但这里有一堆关于如何读取二进制文件的随机信息:

    struct myobject { //so you have your data
        char weight;
        double value;
    };
    //for primitives in a binary format you simply read it in
    std::istream& operator>>(std::istream& in, myobject& data) {
        return in >> data.weight >> data.value; 
        //we don't really care about failures here
    }
    //if you don't know the length, that's harder
    std::istream& operator>>(std::istream& in, std::vector<myobject>& data) {
        int size;
        in >> size; //read the length
        data.clear();
        for(int i=0; i<size; ++i) { //then read that many myobject instances
            myobject obj;
            if (in >> obj)
                data.push_back(obj);
            else //if the stream fails, stop
                break;            
        }
        return in;
    }
    int main() {
        std::ifstream myfile("input.txt", std::ios_base::binary); //open a file
        std::vector<myobject> array;
        if (myfile >> array) //read the data!
            //well that was easy
        else
            std::cerr << "error reading from file";
        return 0;
    };
    

    此外,如果您碰巧知道在哪里可以找到您要查找的数据,您可以使用ifstream 的.seek(position) 成员直接跳到文件中的特定点。

    哦,你只是想将文件的前 12 个字节读取为 8 位整数,然后将接下来的 12 个字节读取为 int32_t?

    int main() {
        std::ifstream myfile("input.txt", std::ios_base::binary); //open a file
    
        std::vector<int8_t> data1(12); //array of 12 int8_t
        for(int i=0; i<12; ++i) //for each int
            myfile >> data1[i]; //read it in
        if (!myfile) return 1; //make sure the read succeeded
    
        std::vector<int32_t> data2(3); //array of 3 int32_t
        for(int i=0; i<3; ++i) //for each int
            myfile >> data2[i]; //read it in
        if (!myfile) return 1; //make sure the read succeeded
    
        //processing
    }
    

    【讨论】:

    • 好吧,我能做到。但是,如果在将前 12 个字节读取为 8 位之后,我想将接下来的 3 个字节读取为 32 位整数怎么办。有没有办法做到,所以不会……乱七八糟?
    • @user2221493:我假设您的意思是 12 个字节作为 32 位整数(总共 3 个整数)。这很容易,您只需阅读更多内容。我在我的问题中展示了一个例子
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-14
    • 2015-06-13
    • 2013-05-17
    • 2010-12-14
    • 2020-09-25
    相关资源
    最近更新 更多