Прочитать бинарный файл в нужном порядке, need advice!

Модератор: Fastman

Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
Аватара пользователя
helloworld
ст. сержант
Сообщения: 368
Зарегистрирован: 2007-10-03 8:06:37
Откуда: Northern Colorado

Прочитать бинарный файл в нужном порядке, need advice!

Непрочитанное сообщение helloworld » 2009-07-03 0:45:59

Граждане помогите прочитать бинарный файл в нужном порядке:

Структура бинарника такая:

Time - 4 bytes
Type - 2 bytes
Subtype - 2 bytes
Length - 4 bytes
Data - размер Lenght

и потом снова - time, type, subtype, length, data и тд.

1. Сначала считываем 4 Time байта
2. Переходим на 4 байта вперед - считываем 2 byte of Type
3. Переходим еще на 4+2 байта вперед - считываем еще 2 байта
4. Еще переход на 4+2+2 байта и считываем 4 byte of LENGH

Далее по значению Length, перепрыгиваем количество байт Lenght, не считывая DATA.

НУЖНО узнать СКОЛЬКО таких конструкций в бинарнике.

Код: Выделить всё


#include <stdio.h>
     
 int main()
    {
      FILE *file;
     
      char buffer1[5];
      char buffer2[3];
      char buffer3[3];
      char buffer4[5];
      int n,m,k,l;
      int i = 0;

      if (file = fopen("example.txt", "rb"))
    
      {

//     while(!feof(file))
//      {

        n = fread(buffer1, 1, 4, file);    //  возвращает количество считанных байтов
        buffer1[n] = 0;
/* a char array is only a string if it has the null character at the end */


	fseek ( file, n , SEEK_SET );

	m = fread(buffer2, 1, 2, file);
        buffer2[m] = 0;

	fseek ( file, n+m, SEEK_SET);

        k = fread(buffer3, 1, 2, file);
        buffer3[k] = 0;
        
        fseek ( file, n+m+k, SEEK_SET);

        l = fread(buffer4, 1, 4, file);
	buffer4[l] = 0;

      fseek ( file, n+m+k+(long int)buffer4, SEEK_SET);

//     i++;	
        
//	}

        fclose(file);
	printf ("Number of reading %d\n", i-1);
        printf("1st %d characters of the file:\n%s\n", n, buffer1);
        printf("2nd %d characters of the file:\n%s\n", m, buffer2);
        printf("3rd %d characters of the file:\n%s\n", k, buffer3);
	printf("4   %d characters of the file:\n%s\n", l, buffer4);

      }
     
      return 0;
    }

В моем случае при влючении структуры while(!feof(file)) , процесс виснет
Помогите прочесть весь файл.

Спасибо.
Последний раз редактировалось helloworld 2009-07-03 1:09:36, всего редактировалось 1 раз.

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Прочитать бинарный файл в нужном порядке, need advice!

Непрочитанное сообщение paradox » 2009-07-03 0:56:15

Граждане помогите прочитать бинарный файл в нужном порядке:
if (file = fopen("example.txt", "rt"))
а открывешь как текстовый
хм

Аватара пользователя
helloworld
ст. сержант
Сообщения: 368
Зарегистрирован: 2007-10-03 8:06:37
Откуда: Northern Colorado

Re: Прочитать бинарный файл в нужном порядке, need advice!

Непрочитанное сообщение helloworld » 2009-07-03 0:58:57

Ок, а как открыть бинарник?
Сейчас example.txt это для теста и там просто набор рандомых чисел.


Аватара пользователя
helloworld
ст. сержант
Сообщения: 368
Зарегистрирован: 2007-10-03 8:06:37
Откуда: Northern Colorado

Re: Прочитать бинарный файл в нужном порядке, need advice!

Непрочитанное сообщение helloworld » 2009-07-03 1:08:53

Прочитал мануал, спасибо.
А что на счет остального?

paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Прочитать бинарный файл в нужном порядке, need advice!

Непрочитанное сообщение paradox » 2009-07-03 1:11:51

да считай сразу весь файл в память и там прыгай как хочеь по нем

Аватара пользователя
helloworld
ст. сержант
Сообщения: 368
Зарегистрирован: 2007-10-03 8:06:37
Откуда: Northern Colorado

Re: Прочитать бинарный файл в нужном порядке, need advice!

Непрочитанное сообщение helloworld » 2009-07-03 1:17:41

Можно пример или ссылку?

paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Прочитать бинарный файл в нужном порядке, need advice!

Непрочитанное сообщение paradox » 2009-07-03 1:21:14

какой пример
узнаешь развер файла fstat
выделаешь malloc размер в байтах
и в цикле по байто считываешь его в выделеную память
а там уже делай что хочешь

указатель на память и прыгаешь как хочешь

вообще я смысла сиего дела невижу

тестовое задание или что это

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

Re: Прочитать бинарный файл в нужном порядке, need advice!

Непрочитанное сообщение zg » 2009-07-03 4:22:12

paradox писал(а):да считай сразу весь файл в память и там прыгай как хочеь по нем
обычно это файлы ресурсов так выглядят, я бы не советовал его считывать сразу и целиком. Тем более, что при чтении с диска считываются сектора, а не байты, поэтому лучше прыгать именно по файлу, а не по оперативке, фс простит.
paradox писал(а):выделаешь malloc размер в байтах
и в цикле по байто считываешь его в выделеную память
угу а если размер файла будет больше чем оператива и своп? да даже если и меньше, но не окажется свободного блока нужного размера? и при этом нужны не все записи, а только 334-ая, которая весит 30б байт :smile:
helloworld писал(а):1. Сначала считываем 4 Time байта
лучше, когда объявляешь структуру и оперируешь только со структурой.

Аватара пользователя
helloworld
ст. сержант
Сообщения: 368
Зарегистрирован: 2007-10-03 8:06:37
Откуда: Northern Colorado

Re: Прочитать бинарный файл в нужном порядке, need advice!

Непрочитанное сообщение helloworld » 2009-07-03 5:57:27

Сейчас переписываю через структуру, позже отпишусь :)

paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Прочитать бинарный файл в нужном порядке, need advice!

Непрочитанное сообщение paradox » 2009-07-03 10:10:40

на практике такое редко случаеться
что бы своп ил озу было меньше чем 256 метров
и желаемый для чтение файл был болше гигабайта

а в его случае так темболее

Аватара пользователя
helloworld
ст. сержант
Сообщения: 368
Зарегистрирован: 2007-10-03 8:06:37
Откуда: Northern Colorado

Re: Прочитать бинарный файл в нужном порядке, need advice!

Непрочитанное сообщение helloworld » 2009-07-04 8:28:08

Вот, переделал.

Код: Выделить всё

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>

typedef struct
{
  uint32_t time;
  uint16_t type;
  uint16_t subtype;
  uint32_t length;
} MRT_Struct __attribute__ ((packed));

int main(int argc, char *argv[])
{
  //unsigned long int num_records = 0;
  unsigned long long int num_records = 0;
  MRT_Struct mrt;
  char buf[4096];
  memset(&mrt, 0, sizeof(mrt));
  char *szFile = "rv4-rib";
  if (argc > 1)
  {
    szFile = argv[1];
  }

  FILE *infile;
  if (NULL == (infile = fopen(szFile, "rb")))
    {
      perror ("fopen");
      exit (EXIT_FAILURE);
    }
    else
    {

     while (!feof (infile))
    {
    fread (&mrt, sizeof (mrt), 1, infile);
    mrt.length = ntohl (mrt.length);

    if (feof (infile))
    {
    break;
    }
    fread (buf, mrt.length, 1, infile);
    num_records++;
    }

    }
  printf ("Number of records in file = %d\n", num_records);
  return 0;
}

Но теперь проблема.
Есть 3 бинарника - один 2 мб, другой 100 мб, третий 700 мб
Последний если читать - seg fault, первые 2 - все ок.

Для 700мб бинарника комментировал строку и программа не вылетала

Код: Выделить всё

fread (buf, mrt.length, 1, infile);
Есть какие идеи?

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

Re: Прочитать бинарный файл в нужном порядке, need advice!

Непрочитанное сообщение zg » 2009-07-04 10:38:17

helloworld писал(а):Есть какие идеи?
zg писал(а):угу а если размер файла будет больше чем оператива и своп? да даже если и меньше, но не окажется свободного блока нужного размера?
paradox писал(а):на практике такое редко случаеться
:smile:
helloworld писал(а):Для 700мб бинарника комментировал строку и программа не вылетала
что именно является целью программы? вылетает потому, что не удаётся выделить свободный блок.

Аватара пользователя
helloworld
ст. сержант
Сообщения: 368
Зарегистрирован: 2007-10-03 8:06:37
Откуда: Northern Colorado

Re: Прочитать бинарный файл в нужном порядке, need advice!

Непрочитанное сообщение helloworld » 2009-07-04 19:00:21

ну проблем с оперативкой\свопом точно нет, проверял на машинке с 4 гб озу
цель - я писал в первом посте - посчитать количество структур в бинарнике.

Аватара пользователя
helloworld
ст. сержант
Сообщения: 368
Зарегистрирован: 2007-10-03 8:06:37
Откуда: Northern Colorado

Re: Прочитать бинарный файл в нужном порядке, need advice!

Непрочитанное сообщение helloworld » 2009-07-04 19:16:02

Не знаю, можно ли это считать решением, но

замена

Код: Выделить всё

 char buf[4096]; 
на

Код: Выделить всё

 int buf[4096];

видимо помогла, в segfault не вылетает :st:

paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Прочитать бинарный файл в нужном порядке, need advice!

Непрочитанное сообщение paradox » 2009-07-04 19:23:36

Код: Выделить всё

mrt.length = ntohl (mrt.length);
как бы проверять надо на длинну буффера прежде чем читать

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

Re: Прочитать бинарный файл в нужном порядке, need advice!

Непрочитанное сообщение zg » 2009-07-04 20:36:38

helloworld писал(а):ну проблем с оперативкой\свопом точно нет, проверял на машинке с 4 гб озу
цель - я писал в первом посте - посчитать количество структур в бинарнике.
чтобы посчитать, необязательно считывать весь файл :smile: есть прекрасная функция

Код: Выделить всё

     int
     fseek(FILE *stream, long offset, int whence);

DESCRIPTION
     The fseek() function sets the file position indicator for the stream
     pointed to by stream.  The new position, measured in bytes, is obtained
     by adding offset bytes to the position specified by whence.  If whence is
     set to SEEK_SET, SEEK_CUR, or SEEK_END, the offset is relative to the
     start of the file, the current position indicator, or end-of-file,
     respectively.  A successful call to the fseek() function clears the end-
     of-file indicator for the stream and undoes any effects of the ungetc(3)
     and ungetwc(3) functions on the same stream.
как только ты узнал местополжение новой структуры, то перемещаешь указатель туда и считываешь новый заголовок, затем опять высчитываешь местоположение следующего заголовка и т.д., пока файл не кончится

ЗЫ можешь выложить небольшой пример бинарного файла?

Аватара пользователя
Case
рядовой
Сообщения: 30
Зарегистрирован: 2008-08-22 21:21:15
Откуда: Ижевск, Россия

Re: Прочитать бинарный файл в нужном порядке, need advice!

Непрочитанное сообщение Case » 2009-10-23 20:33:27

paradox писал(а): man fopen
"rb"
или
"r+b
В мане на fopen прочитал вот что:

Код: Выделить всё

The mode string can also include the letter ``b'' either as a third char-
     acter or as a character between the characters in any of the two-charac-
     ter strings described above.  This is strictly for compatibility with
     ISO/IEC 9899:1990 (``ISO C90'') and has no effect; the ``b'' is ignored.

Получается, что "b" в режиме открытия вообще ничего не решает? Или я не так понял?