Чтение файла, начиная с конца в MATLAB - PullRequest
2 голосов
/ 01 июля 2011

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

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

timestamp accx accy accz gyrox gyroy gyroz magx magy magz

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

Ответы [ 3 ]

1 голос
/ 01 июля 2011

Если вы работаете в системе на основе 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, чтобы проверить, является ли новая отметка времени уже частью ранее прочитанных вами отметок времени.

0 голосов
/ 01 июля 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?
0 голосов
/ 01 июля 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 строк.

...