Поиск определенных примитивов в двоичном файле

Есть ли способы найти конкретный примитив в двоичном файле (например, fread в MATLAB или BinaryReadLists в Mathematica)? В частности, я хочу сканировать свой файл до тех пор, пока он не достигнет, скажем, числа точности int8_t, затем сохраните его в переменной, а затем просканируйте другой примитив (беззнаковый символ, двойной и т. д.)?

Я переписываю код из MATLAB, который делает это, поэтому формат файла известен.

Я хочу прочитать n байтов только указанного типа (32-битный int, char, ..) в файле. Пример: читать только первые 12 байт моего файла, если они возвращаются как 8-битные целые числа.


person DashControl    schedule 28.03.2013    source источник
comment
Неа. Если у вас есть двоичный файл, но вы не знаете формат содержимого, то невозможно определить типы чего-либо. int, float и char* неразличимы.   -  person Mooing Duck    schedule 29.03.2013
comment
Спасибо. Я должен упомянуть, но я знаю формат. Я переписываю код из MATLAB, который делает это.   -  person DashControl    schedule 29.03.2013
comment
Если вы знаете формат, то..... Я совершенно не понимаю вашего вопроса. Если вы знаете формат, зачем вы сканируете, пока не найдете int8_t? Просто скажите нам, что вы хотите сделать, и, скорее всего, это легко.   -  person Mooing Duck    schedule 29.03.2013
comment
Я хочу прочитать n байтов только указанного типа (32-битный int, char, ..) в файле. Пример: читать только первые 12 байт моего файла, если они возвращаются как 8-битные целые числа.   -  person DashControl    schedule 29.03.2013


Ответы (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;
};

Кроме того, вы можете использовать член .seek(position) для ifstream, чтобы перейти непосредственно к определенной точке файла, если вы знаете, где найти данные, которые вы ищете.

О, вы просто хотите прочитать первые 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
}
person Mooing Duck    schedule 28.03.2013
comment
Точно, я могу это сделать. Но что, если я хочу прочитать следующие 3 байта как 32-битные целые числа после того, как я прочитал первые 12 как 8-битные. Можно ли как-то это сделать, чтобы не было... грязно? - person DashControl; 29.03.2013
comment
@ user2221493: Я предполагаю, что вы имеете в виду 12 байтов как 32-битные целые числа (всего 3 целых числа). Это довольно просто, вы просто читаете больше. Я показал пример в своем вопросе - person Mooing Duck; 29.03.2013