2016-06-10 4 views
0

Недавно я задал еще один вопрос о разборе двоичного файла, и я вроде как получил его для работы благодаря всем здесь.Чтение двоичного файла пошагово

https://stackoverflow.com/questions/37755225/need-help-reading-binary-file-to-a-structure?noredirect=1#comment62983158_37755225

Но я сейчас сталкиваются с новой проблемой, и я нуждаюсь в помощи, пожалуйста, голые со мной.

Мой бинарный файл выглядит примерно так, но гораздо дольше ...

ST ......... ¸. ° Ý.ø ... 0.œ ...... ..... ESZ4 1975 .......... IYH.testDBDBDBDBST ........... ° Ý.ø ............... .... DBDBDBDBST ......... P.'Ý.ø ... 0.œ ........... ESZ4 1975 .......... HTC .testDBDBDBDBST ......... <,'Ý.ø ................... DBDBDBDBST ......... ƒD.Þ. ø ... 0.œ ........... ESZ4 1975 .......... ARM.testDBDBDBDBST ......... «E.Þ.ø .. ................. DBDBDBDB

В принципе, каждое сообщение начинается с «ST» и заканчивается «DBDBDBDB». Цель состоит в том, чтобы проанализировать каждое сообщение и сохранить сообщение в структуре данных. Кроме того, каждое сообщение отличается в зависимости от типа, и у другого типа сообщения будут дополнительные члены.

Проблема у меня есть, я понятия не имею, как итерации через этот двоичный файл ... Если его обычный файл, я могу просто сделать while (getline (файл, s)), но как насчет бинарного файла ?? Есть ли способ сказать, найти первые «ST» и «DBDBDBDB» и проанализировать средний материал, а затем перейти к следующему набору ST и DB? Или каким-то образом прочитайте файл, постепенно отслеживая, где я?

Приносим извинения за время размещения столько кода.

#pragma pack(push, 1) 
struct Header 
{ 
    uint16_t marker; 
    uint8_t msg_type; 
    uint64_t sequence_id; 
    uint64_t timestamp; 
    uint8_t msg_direction; 
    uint16_t msg_len; 
}; 
#pragma pack(pop) 
struct OrderEntryMessage 
{ 
    Header header; 
    uint64_t price; 
    uint32_t qty; 
    char instrument[10]; 
    uint8_t side; 
    uint64_t client_assigned_id; 
    uint8_t time_in_force; 
    char trader_tag[3]; 
    uint8_t firm_id; 
    char firm[256] ; 
    char termination_string[8]; 
}; 

struct AcknowledgementMessage 
{ 
    Header header; 
    uint32_t order_id; 
    uint64_t client_id; 
    uint8_t order_status; 
    uint8_t reject_code; 
    char termination_string[8]; 
}; 

struct OrderFillMessage 
{ 
    Header header; 
    uint32_t order_id; 
    uint64_t fill_price; 
    uint32_t fill_qty; 
    uint8_t no_of_contras; 
    uint8_t firm_id; 
    char trader_tag[3]; 
    uint32_t qty; 
    char termination_string[8]; 
}; 
void TradeDecoder::createMessage() 
{ 
    ifstream file("example_data_file.bin", std::ios::binary); 

    //I want to somehow Loop here to keep looking for headers ST 

    Header h; 
    file.read ((char*)&h.marker, sizeof(h.marker)); 
    file.read ((char*)&h.msg_type, sizeof(h.msg_type)); 
    file.read ((char*)&h.sequence_id, sizeof(h.sequence_id)); 
    file.read ((char*)&h.timestamp, sizeof(h.timestamp)); 
    file.read ((char*)&h.msg_direction, sizeof(h.msg_direction)); 
    file.read ((char*)&h.msg_len, sizeof(h.msg_len)); 
    file.close(); 

    switch(h.sequence_id) 
    { 
     case 1: 
      createOrderEntryMessage(h); //this methods creates a OrderEntryMessage with the header 
     break; 
     case 2: 
      createOrderAckMessage(h); //same as above 
     break; 
     case 3: 
      createOrderFillMessage(h); //same as above 
     break; 
     default: 
     break; 
    } 
} 

Много много спасибо .....

+1

Если вы собираетесь обрабатывать двоичные файлы, вы должны установили своего рода макет, описывающий запись файла. Например, байты 0-4 - это размер, байты 5-15 - это имя, байты 16-20 и т. Д. Из вашего сообщения, похоже, единственное, что вы описали таким образом, это запись заголовка - вы сделали Не делайте этого для других типов записей, найденных в файле. – PaulMcKenzie

+0

Другие типы также указаны. Каждое сообщение содержит заголовок, а размер сообщения указывается в заголовке. –

+1

Вы считали [читать()] (http://en.cppreference.com/w/cpp/io/basic_istream/read)? Поскольку вы говорите, что заголовок имеет эту информацию, вы читаете количество указанных байт. – PaulMcKenzie

ответ

0

Вы можете прочитать весь файл в буфер, а затем разобрать буфер в соответствии с вашими требованиями.

Я хотел бы использовать

fread 

читать весь файл в буфер, а затем процесс/разбор буфера побайтно.

Это пример:

/* fread - read an entire file to a buffer */ 
#include <stdio.h> 
#include <stdlib.h> 

int main() { 
    FILE * pFile; 
    long lSize; 
    char * buffer; 
    size_t result; 

    pFile = fopen ("myfile.bin" , "rb"); 
    if (pFile==NULL) 
    {fputs ("File error",stderr); exit (-1);} 

    // obtain file size: 
    fseek (pFile , 0 , SEEK_END); 
    lSize = ftell (pFile); 
    rewind (pFile); 

    // allocate memory to contain the whole file: 
    buffer = (char*) malloc (sizeof(char)*lSize); 
    if (buffer == NULL) // malloc failed 
    {fputs ("Memory error",stderr); exit (-2);} 

    // copy the file into the buffer: 
    result = fread (buffer,1,lSize,pFile); 
    if (result != lSize) 
    {fputs ("Reading error",stderr); exit (-3);} 

    // the whole file is now loaded in the memory buffer. 
    // you can process the whole buffer now: 

    // for (int i=0; i<lSize;i++) 
    // { 
    // processBufferByteByByte(buffer[i]); 
    // } 
    // or 
    // processBuffer(buffer,lSize); 

    // terminate 
    fclose (pFile); 
    free (buffer); 
    return 0; 
} 
Смежные вопросы