Чтение файла, начиная с конца в MATLAB

Мне было интересно, знает ли кто-нибудь, как открыть и прочитать файл в MATLAB, где вы начинаете чтение с конца файла. Файл постоянно обновляется (с некоторой непостоянной скоростью между чтениями), и я хочу каждый раз читать последние шесть строк файла.

Я бы также включил тест, чтобы убедиться, что я не перечитываю одни и те же строки дважды. Каждая строка отформатирована следующим образом (каждая переменная представляет собой число с плавающей запятой):

timestamp accx accy accz gyrox gyroy gyroz magx magy magz

Я пытался использовать fseek, чтобы изменить позицию на последнюю строку файла, но это позволяет мне читать только последнюю строку файла, я думаю, а не читать файл назад, если я не укажу определенное количество байтов, что Я бы не знал точное количество байтов.


person Veridian    schedule 30.06.2011    source источник


Ответы (3)


Если вы работаете в системе на основе Unix (Linux/Mac), вы можете напрямую использовать системные команды, чтобы делать то, что хотите. Вот пример тестового файла:

12345 accx accy accz gyrox gyroy gyroz magx magy magz
23456 accx accy accz gyrox gyroy gyroz magx magy magz
34567 accx accy accz gyrox gyroy gyroz magx magy magz
45678 accx accy accz gyrox gyroy gyroz magx magy magz
56789 accx accy accz gyrox gyroy gyroz magx magy magz
67890 accx accy accz gyrox gyroy gyroz magx magy magz

Вы можете прочитать его с помощью tail в unix и непосредственно в MATLAB с помощью команды system.

[~, str]=system('tail -n 2 filename')
str =

    56789 accx accy accz gyrox gyroy gyroz magx magy magz
    67890 accx accy accz gyrox gyroy gyroz magx magy magz

Замените 2 в -n 2 на количество строк, которые вы хотите прочитать.

Затем, чтобы убедиться, что вы читаете одну и ту же строку, вы можете сохранить временные метки (первый столбец). Самый простой способ сделать это снова позволить unix сделать это за вас.

[~, timestamp]=system('tail -n 2 filename | awk ''{print $1}''')

timestamp =

56789
67890

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

person abcd    schedule 01.07.2011

Единственный способ узнать, какую строку вы читаете из файла, — это начать с самого начала и подсчитать новые строки. Невозможно начать с конца файла и сразу перейти назад на определенное количество строк.

Вы можете написать функцию, которая читает в обратном направлении с конца файла, пока не увидит N новых строк, а затем выводит этот фрагмент. Именно так работает tail. Вот комментарий от GNU tail.c:

/* Print the last N_LINES lines from the end of file FD.
   Go backward through the file, reading `BUFSIZ' bytes at a time (except
   probably the first), until we hit the start of the file or have
   read NUMBER newlines.
   START_POS is the starting position of the read pointer for the file
   associated with FD (may be nonzero).
   END_POS is the file offset of EOF (one larger than offset of last byte).
   Return true if successful.  */

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

person nibot    schedule 01.07.2011

Вы можете выполнить поиск в конце файла (используя fseek(), чтобы установить позицию для EOF задолго до ваших 6 строк, а затем выполнить поиск последних 6 или 7 символов новой строки и с помощью find(). Затем вы можете извлечь свои данные, потому что вы знаете где последние 6 строк находятся в исходном фрагменте, который вы читаете.

fid=fopen(filename,'r');
fseek(fid,500,'eof');
dat=fread(fid,Inf,'*char');
linestart=find(dat=="\n",7,'last'); % choose 7 newlines because there will be one at the end?
person mor22    schedule 01.07.2011