Страница 1 из 1
Прочитать бинарный файл в нужном порядке, need advice!
Добавлено: 2009-07-03 0:45:59
helloworld
Граждане помогите прочитать бинарный файл в нужном порядке:
Структура бинарника такая:
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)) , процесс виснет
Помогите прочесть весь файл.
Спасибо.
Re: Прочитать бинарный файл в нужном порядке, need advice!
Добавлено: 2009-07-03 0:56:15
paradox
Граждане помогите прочитать бинарный файл в нужном порядке:
if (file = fopen("example.txt", "rt"))
а открывешь как текстовый
хм
Re: Прочитать бинарный файл в нужном порядке, need advice!
Добавлено: 2009-07-03 0:58:57
helloworld
Ок, а как открыть бинарник?
Сейчас example.txt это для теста и там просто набор рандомых чисел.
Re: Прочитать бинарный файл в нужном порядке, need advice!
Добавлено: 2009-07-03 1:04:09
paradox
man fopen
"rb"
или
"r+b"
Re: Прочитать бинарный файл в нужном порядке, need advice!
Добавлено: 2009-07-03 1:08:53
helloworld
Прочитал мануал, спасибо.
А что на счет остального?
Re: Прочитать бинарный файл в нужном порядке, need advice!
Добавлено: 2009-07-03 1:11:51
paradox
да считай сразу весь файл в память и там прыгай как хочеь по нем
Re: Прочитать бинарный файл в нужном порядке, need advice!
Добавлено: 2009-07-03 1:17:41
helloworld
Можно пример или ссылку?
Re: Прочитать бинарный файл в нужном порядке, need advice!
Добавлено: 2009-07-03 1:21:14
paradox
какой пример
узнаешь развер файла fstat
выделаешь malloc размер в байтах
и в цикле по байто считываешь его в выделеную память
а там уже делай что хочешь
указатель на память и прыгаешь как хочешь
вообще я смысла сиего дела невижу
тестовое задание или что это
Re: Прочитать бинарный файл в нужном порядке, need advice!
Добавлено: 2009-07-03 4:22:12
zg
paradox писал(а):да считай сразу весь файл в память и там прыгай как хочеь по нем
обычно это файлы ресурсов так выглядят, я бы не советовал его считывать сразу и целиком. Тем более, что при чтении с диска считываются сектора, а не байты, поэтому лучше прыгать именно по файлу, а не по оперативке, фс простит.
paradox писал(а):выделаешь malloc размер в байтах
и в цикле по байто считываешь его в выделеную память
угу а если размер файла будет больше чем оператива и своп? да даже если и меньше, но не окажется свободного блока нужного размера? и при этом нужны не все записи, а только 334-ая, которая весит 30б байт
helloworld писал(а):1. Сначала считываем 4 Time байта
лучше, когда объявляешь структуру и оперируешь только со структурой.
Re: Прочитать бинарный файл в нужном порядке, need advice!
Добавлено: 2009-07-03 5:57:27
helloworld
Сейчас переписываю через структуру, позже отпишусь

Re: Прочитать бинарный файл в нужном порядке, need advice!
Добавлено: 2009-07-03 10:10:40
paradox
на практике такое редко случаеться
что бы своп ил озу было меньше чем 256 метров
и желаемый для чтение файл был болше гигабайта
а в его случае так темболее
Re: Прочитать бинарный файл в нужном порядке, need advice!
Добавлено: 2009-07-04 8:28:08
helloworld
Вот, переделал.
Код: Выделить всё
#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мб бинарника комментировал строку и программа не вылетала
Есть какие идеи?
Re: Прочитать бинарный файл в нужном порядке, need advice!
Добавлено: 2009-07-04 10:38:17
zg
helloworld писал(а):Есть какие идеи?
zg писал(а):угу а если размер файла будет больше чем оператива и своп? да даже если и меньше, но не окажется свободного блока нужного размера?
paradox писал(а):на практике такое редко случаеться
helloworld писал(а):Для 700мб бинарника комментировал строку и программа не вылетала
что именно является целью программы? вылетает потому, что не удаётся выделить свободный блок.
Re: Прочитать бинарный файл в нужном порядке, need advice!
Добавлено: 2009-07-04 19:00:21
helloworld
ну проблем с оперативкой\свопом точно нет, проверял на машинке с 4 гб озу
цель - я писал в первом посте - посчитать количество структур в бинарнике.
Re: Прочитать бинарный файл в нужном порядке, need advice!
Добавлено: 2009-07-04 19:16:02
helloworld
Не знаю, можно ли это считать решением, но
замена
на
видимо помогла, в segfault не вылетает

Re: Прочитать бинарный файл в нужном порядке, need advice!
Добавлено: 2009-07-04 19:23:36
paradox
как бы проверять надо на длинну буффера прежде чем читать
Re: Прочитать бинарный файл в нужном порядке, need advice!
Добавлено: 2009-07-04 20:36:38
zg
helloworld писал(а):ну проблем с оперативкой\свопом точно нет, проверял на машинке с 4 гб озу
цель - я писал в первом посте - посчитать количество структур в бинарнике.
чтобы посчитать, необязательно считывать весь файл

есть прекрасная функция
Код: Выделить всё
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.
как только ты узнал местополжение новой структуры, то перемещаешь указатель туда и считываешь новый заголовок, затем опять высчитываешь местоположение следующего заголовка и т.д., пока файл не кончится
ЗЫ можешь выложить небольшой пример бинарного файла?
Re: Прочитать бинарный файл в нужном порядке, need advice!
Добавлено: 2009-10-23 20:33:27
Case
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" в режиме открытия вообще ничего не решает? Или я не так понял?