C:只读取文件的最后一行。 没有循环

使用C,有没有办法读取文件的最后一行而不循环它的整个内容?

事情是该文件包含数百万行,每行包含一个整数(long long int)。 文件本身可能非常大,我估计甚至高达1000mb。 我确信最后一行不会超过55位数,但也可能只有2位数。 使用任何类型的数据库都没有选择……我已经考虑过了。

也许这是一个愚蠢的问题,但是来自PHP背景我觉得很难回答。 我到处看,但一无所获。

目前我正在使用:

if ((fd = fopen(filename, "r")) != NULL) // open file { fseek(fd, 0, SEEK_SET); // make sure start from 0 while(!feof(fd)) { memset(buff, 0x00, buff_len); // clean buffer fscanf(fd, "%[^\n]\n", buff); // read file *prefer using fscanf } printf("Last Line :: %d\n", atoi(buff)); // for testing I'm using small integers } 

这样我循环文件的内容,一旦文件大于~500k行,事情就会慢下来……

先感谢您。 格言

如果有最大线长,请在结束前寻找该距离。 读到最后,找到缓冲区中的最后一行。

如果没有最大行长度,猜测一个合理的值,最后读取那么多,如果没有行尾,请加倍猜测并再试一次。

在你的情况下:

 /* max length including newline */ static const long max_len = 55 + 1; /* space for all of that plus a nul terminator */ char buf[max_len + 1]; /* now read that many bytes from the end of the file */ fseek(fd, -max_len, SEEK_END); ssize_t len = read(fd, buf, max_len); /* don't forget the nul terminator */ buf[len] = '\0'; /* and find the last newline character (there must be one, right?) */ char *last_newline = strrchr(buf, '\n'); char *last_line = last_newline+1; 

刚刚fseek到fileSize - 55并向前阅读?

打开"rb"以确保您正在阅读二进制文件。 然后fseek(..., SEEK_END)并开始从后面读取字节,直到找到第一行分隔符(如果你知道最大行长度是55个字符,读取55个字符……)。

好。 这一切对我有用。 我学到了新东西。 文件41mb大的最后一行和> 500k行被立即读取。 感谢你们所有人,特别是“无用”(喜欢你的绰号的争议,顺便说一句)。 我将在这里发布代码,希望将来的其他人可以从中受益:

只读取文件的最后一行:

文件的结构是附加一个新行的方式,我确信任何行都比我的情况下短55个字符:

 file contents: ------------------------ 2943728727 3129123555 3743778 412912777 43127787727 472977827 ------------------------ 

注意附加的新行。

 FILE *fd; // File pointer char filename[] = "file.dat"; // file to read static const long max_len = 55+ 1; // define the max length of the line to read char buff[max_len + 1]; // define the buffer and allocate the length if ((fd = fopen(filename, "rb")) != NULL) { // open file. I omit error checks fseek(fd, -max_len, SEEK_END); // set pointer to the end of file minus the length you need. Presumably there can be more than one new line caracter fread(buff, max_len-1, 1, fd); // read the contents of the file starting from where fseek() positioned us fclose(fd); // close the file buff[max_len-1] = '\0'; // close the string char *last_newline = strrchr(buff, '\n'); // find last occurrence of newlinw char *last_line = last_newline+1; // jump to it printf("captured: [%s]\n", last_line); // captured: [472977827] } 

干杯! 格言