| re: A better way to tail a file
Hi,
Look for the last modification date/time for the file. Install a timer to
read this date/time every xxx seconds or minutes
I f the modification has been changed read the file until the end is reached
i.e.
......
read file until end
fill variable lastmodified with last time file modified;
......
while(true)
{
signal SIGALRM, timerEvent );
alarm( 5 ) // every 5 seconds
}
.......
void timerEvent()
{
struct stat st;
// fd file descriptor open file
fstat( fd, &st );
if( st.st_mtime != lastmodified )
{
read file until end of file
}
lastmodified = st.st_mtime;
}
"Count Dracula" <lk3a@esinet.net> schreef in bericht
news:fcadc9c4.0308091318.3a6a5050@posting.google.c om...[color=blue]
> Is there a way to write a c++ program that will
> print out the last few lines of a file without reading
> the whole file? The implementations of 'tail' I have
> seen all appear to be system dependent. I am looking for
> a standard (portable) c++ solution that will do just a
> fraction of tail's functionality. To make a long story short,
> I am looking for suggestions that may help me improve the
> speed of the following implementation for long input files:
>
> /*
> Command line utility to display the last few lines of a text file.
>
> Usage: (1) tail <filename>
> (2) tail <filename> <number of lines>
>
> <filename> is the name of the file whose last few lines you want to
> display
> <number of lines> is the number of lines you want to display
> (default is NumberOfLines)
>
> Implementation note: this is an inefficient implementation that
> reads the whole file
> only to display a few lines from the end of the file.
> */
>
> #include <string>
> #include <iostream>
> #include <fstream>
> #include <cstdlib>
> #include <deque>
>
> // Forward declarations
> bool writetail(const std::string & filename, long numlines);
> void usage(long NumberOfLines);
>
> int main (int argc, char** argv)
> {
> const long NumberOfLines = 10;
> long numlines;
> std::string filename;
> switch (argc)
> {
> case 2:
> filename = argv[1];
> numlines = NumberOfLines;
> break;
> case 3:
> filename = argv[1];
> numlines = strtol(argv[2], NULL, 10);
> if (numlines <= 0 || errno == ERANGE)
> {
> std::cerr << argv[0] << ": error in second command line
> argument" << '\n';
> usage(NumberOfLines);
> return 1;
> }
> break;
> default:
> std::cerr << argv[0] << ": missing command line arguments" <<
> '\n';
> usage(NumberOfLines);
> return 1;
> }
> bool status = writetail(filename, numlines);
> if (!status)
> {
> std::cerr << argv[0] << ": execution errors" << '\n';
> usage(NumberOfLines);
> return 1;
> }
> return 0;
> }
>
> bool writetail(const std::string & filename, long numlines)
> {
> std::ifstream input(filename.c_str());
> if (!input)
> {
> std::cerr << "writehead: error opening file: " << filename <<
> '\n';
> return false;
> }
> std::string s;
> std::deque<std::string> lines;
> long kount = 0;
> while (std::getline(input, s))
> {
> lines.push_back(s);
> ++kount;
> if (kount == numlines) break;
> }
> while (std::getline(input, s))
> {
> lines.pop_front();
> lines.push_back(s);
> }
> std::deque<std::string>::iterator p;
> for (p = lines.begin(); p < lines.end(); ++p)
> std::cout << *p << '\n';
> input.close();
> return true;
> }
>
> void usage(long NumberOfLines)
> {
> std::cerr << "usage: tail <filename> <number of lines (optional)>\n"
> <<
> " <filename> is the name of the file whose last
> few lines you want to display\n" <<
> " <number of lines> is the number of lines you
> want to display (default is " <<
> NumberOfLines << ")\n";
> }[/color] |