给定一个包含动态数据的大文件,编写一个程序,在任何时候读取文件的最后n行,而不读取整个文件。这个问题类似于linux中的tail命令,它显示文件的最后几行。它主要用于查看日志文件更新,因为这些更新会附加到日志文件中。
null
资料来源: 微软采访
我们强烈建议您尽量减少浏览器,并先自己尝试。
问题主要集中在以下方面——
1.程序不应读取整个文件。 2.程序应处理传入的动态数据,并在任意点返回最后n行。 3.在读取最后n行之前,程序不应关闭输入流。
下面是C++实现
// C++ program to implement your own tail #include <bits/stdc++.h> using namespace std; #define SIZE 100 // Utility function to sleep for n seconds void sleep(unsigned int n) { clock_t goal = n * 1000 + clock (); while (goal > clock ()); } // function to read last n lines from the file // at any point without reading the entire file void tail( FILE * in, int n) { int count = 0; // To count '' characters // unsigned long long pos (stores upto 2^64 – 1 // chars) assuming that long long int takes 8 // bytes unsigned long long pos; char str[2*SIZE]; // Go to End of file if ( fseek (in, 0, SEEK_END)) perror ( "fseek() failed" ); else { // pos will contain no. of chars in // input file. pos = ftell (in); // search for '' characters while (pos) { // Move 'pos' away from end of file. if (! fseek (in, --pos, SEEK_SET)) { if ( fgetc (in) == '' ) // stop reading when n newlines // is found if (count++ == n) break ; } else perror ( "fseek() failed" ); } // print last n lines printf ( "Printing last %d lines -" , n); while ( fgets (str, sizeof (str), in)) printf ( "%s" , str); } printf ( "" ); } // Creates a file and prints and calls tail() for // 10 different values of n (from 1 to 10) int main() { FILE * fp; char buffer[SIZE]; // Open file in binary mode // wb+ mode for reading and writing simultaneously fp = fopen ( "input.txt" , "wb+" ); if (fp == NULL) { printf ( "Error while opening file" ); exit (EXIT_FAILURE); } srand ( time (NULL)); // Dynamically add lines to input file // and call tail() each time for ( int index = 1; index <= 10; index++) { /* generate random logs to print in input file*/ for ( int i = 0; i < SIZE - 1; i++) buffer[i] = rand () % 26 + 65; // A-Z buffer[SIZE] = ' ' ; /* code to print timestamp in logs */ // get current calendar time time_t ltime = time (NULL); // asctime() returns a pointer to a string // which represents the day and time char * date = asctime ( localtime (<ime)); // replace the '' character in the date string // with ' ' to print on the same line. date[ strlen (date)-1] = ' ' ; /* Note in text mode '' appends two characters, so we have opened file in binary mode */ fprintf (fp, "Line #%d [%s] - %s" , index, date, buffer); // flush the input stream before calling tail fflush (fp); // read last index lines from the file tail(fp, index); // sleep for 3 seconds // note difference in timestamps in logs sleep(3); } /* close the file before ending program */ fclose (fp); return 0; } |
需要注意的几点—— 1.此代码无法在联机编译器上运行,因为它需要文件创建权限。当运行本地机器时,它会生成示例输入文件“input.txt”,并将数据动态写入其中10次,每次调用tail()函数。
2.我们应该避免使用fseek()和ftell()处理大文件(以GB为单位),因为它们在long int类型的文件位置上操作。请改用_fseeki64(),_ftelli64()。
3.unsigned long的最大允许值为2 32 –1(假设unsigned long需要4个字节)。它可以用于大小小于4 GB的文件。
4.无符号long long的最大允许值为2 64 –1(假设unsigned long需要8字节)。它可以用于大小超过4 GB的文件。
本文由 阿迪蒂亚·戈尔 。如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请发表评论
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END