在 MATLAB 中从末尾开始读取文件

发布于 2024-11-17 21:24:31 字数 312 浏览 4 评论 0原文

我想知道是否有人知道如何在 MATLAB 中打开和读取文件,从文件末尾开始读取。该文件不断更新(在读取之间以某种非恒定速率),我想每次读取文件的最后六行。

我还想包括一个测试来验证我不会重复阅读相同的行两次。每行的格式如下(每个变量都是浮点数):

timestamp accx accy accz gyrox gyroy gyroz magx magy magz

我试图使用 fseek 将位置更改为文件的最后一行,但这只允许我读取我认为文件的最后一行,除非我指定一定数量的字节,否则不会向后读取文件,而我无法确切知道字节数。

I was wondering if anyone knows how to open and read from a file in MATLAB where you begin reading from the end of the file. The file is constantly being updated (at some nonconstant rate between reads) and I want to read the last six lines of the file each time.

I would also to include a test to verify that I don't reread the same lines twice. Each line is formatted as follows (each variable is a floating point number):

timestamp accx accy accz gyrox gyroy gyroz magx magy magz

I was trying to use fseek, to change the position to the last line of the file, but this only allows me to read the last line of the file I think, not read the file backwards unless I specify a certain number of bytes, which I wouldn't know the number of bytes exactly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一念一轮回 2024-11-24 21:24:31

如果您使用的是基于 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

您可以在 unix 上使用 tail 读取它,并使用 system 命令直接将其读取到 MATLAB 中。

[~, 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

-n 2 中的 2 替换为您想要读取的行数。

接下来,为了确保您读取同一行,您可能需要存储时间戳(第一列)。最简单的方法是再次让 unix 为您做这件事,

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

timestamp =

56789
67890

使用 str2num 将其转换为数字,并在每次读取时存储这些数字,然后使用函数 ismember 检查是否新的时间戳已经是您之前读取的时间戳的一部分。

If you're on a unix based system (Linux/Mac), you can directly use system commands to do what you want. Here's a sample test file:

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

You can read it using tail on unix and into MATLAB directly using the system command.

[~, 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

Replace the 2 in -n 2 with how many ever lines you want to read.

Next, to make sure you read the same line, you might want to store the timestamps (first column). The simplest way to do that is again let unix do it for you

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

timestamp =

56789
67890

Convert it to numbers using str2num and store these each time you read and then use the function ismember to check if a new timestamp is already part of your previously read timestamps.

演多会厌 2024-11-24 21:24:31

了解您正在从文件中读取哪一行的唯一方法是从头开始并计算换行数。没有办法从文件末尾开始直接向后查找一定行数。

您可以编写一个函数,从文件末尾向后读取,直到看到 N 个换行符,然后输出该块。这正是 tail 的工作原理。这是来自 GNU tail.c< 的评论/code>

/* 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 行。

The only way to know what line you are reading from a file is to start at the beginning and count newlines. There is no way to start at the end of the file and directly seek backwards by a certain number of lines.

You could write a function that reads backwards from the end of the file until it sees N newlines, and then outputs this chunk. This is precisely how tail works. Here is a comment from 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.  */

If the file is not too huge, the easiest thing to do would be to write a function that reads a line at a time, only keeping the last N lines.

哎呦我呸! 2024-11-24 21:24:31

您可以搜索文件的末尾块(使用 fseek() 在 6 行之前设置 EOF 的位置,然后搜索最后 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?

You could search the end chunk of the file (using fseek() to set the position for the EOF well in advance of your 6 lines and then search for the last 6 or 7 newline characters and with find(). Then you could extract your data because you know where the last 6 lines are in the original chunk that you read.

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?
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文