2017-12-27 12 views
1

Ich habe eine Protokolldatei und ich möchte ein Programm in C schreiben, um diese Protokolldatei zu lesen und auf neue Daten warten, wenn EOF erreicht ist. Ich möchte nicht tail -f in meinem Code verwenden. Ich habe versucht, den folgenden Code, aber es funktioniert nicht:Lesen Sie eine kontinuierlich aktualisierte Datei und warten auf neue Daten in die Datei geschrieben werden C

#define _GNU_SOURCE 1 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/inotify.h> 
#include <unistd.h> 

#define PATH "/home/sanket/demo.txt" 

int main(void) 
{ 
     FILE * fp; 
    int fd; 
    char * line = NULL; 
    size_t len = 0; 
    ssize_t read1; 
    int notify_fd; 
    int wd,length ,i=0; 
    char buffer[EVENT_BUF_LEN]; 

    fp = fopen(PATH, "r"); 
    if (fp == NULL) 
      exit(EXIT_FAILURE); 

    fd = fileno(fp); 
    while (1) 
    { 
      read1 = getline(&line, &len, fp); 
      if(read1 != -1) 
        printf("%s",line); 
      else 
      { 
        lseek(fd,0,SEEK_DATA); 
      } 
    } 

    if (line) 
      free(line); 
    exit(EXIT_SUCCESS); 
} 
+0

Werfen Sie einen Blick [hier] (https://stackoverflow.com/questions/5474232/how-to-loop-through-only-active-file-descriptors-from-fd-set-result-from-select) – phyloflash

+0

Sie müssen nicht suchen, wenn Sie das Ende der Datei erreichen, nur schlafen und wieder lesen – Pras

Antwort

4

Wenn Sie das erste Ende der Datei erreicht, wird der Eingangsstrom-Flag für EOF gesetzt. Dies muss gelöscht werden, bevor Sie den Betrieb fortsetzen können (clearerr(fp)). Sie sollten normalerweise auch schlafen. (Mit lseek() auf dem Dateideskriptor mit dem Strom verbunden ist, wird nicht helfen.)

Hier ist ein Programm, das auf Ihrem Code - ich hatte den Wert von PATH zu ändern (was keine besonders guter Name ist):

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

#define PATH "demo.txt" 

int main(void) 
{ 
    FILE * fp; 
    char * line = NULL; 
    size_t len = 0; 

    fp = fopen(PATH, "r"); 
    if (fp == NULL) 
    { 
     perror(PATH); 
     exit(EXIT_FAILURE); 
    } 

    while (1) 
    { 
     if (getline(&line, &len, fp) != -1) 
      printf("%s",line); 
     else 
     { 
      printf("EOF\n"); 
      sleep(1); 
      clearerr(fp); 
     } 
    } 

    if (line) 
     free(line); 
    return(EXIT_SUCCESS); 
} 

Wenn Sie ein Programm haben, das Daten zu einer Datei generiert, können Sie damit testen. Ich habe ein Programm dribbler so macht, dass:

$ dribbler -f demo.txt -s 1.5 -r 0.5 & 
[1] 20678 
$ cat demo.txt 
0: message written to file 
1: message written to file 
2: message written to file 
$ tail11 
0: message written to file 
1: message written to file 
2: message written to file 
3: message written to file 
4: message written to file 
5: message written to file 
EOF 
6: message written to file 
EOF 
EOF 
7: message written to file 
EOF 
8: message written to file 
EOF 
EOF 
9: message written to file 
EOF 
10: message written to file 
EOF 
11: message written to file 
EOF 
EOF 
^C 
$ 

Die Optionen dribbler sind:

Usage: dribbler [-hlntV][-s nap.time][-r std.dev][-f outfile][-i infile][-m message][-o openstr][-F format] 
    -V   Print version information and exit 
    -f outfile Write to named file (dribbler.out) 
    -h   Print this help message and exit 
    -i infile Read lines from input file 
    -l   Loop back to start of input file on EOF 
    -m message Write message on each line of output 
    -n   Number lines read from input file 
    -o openstr Flags passed to fopen() (a+) 
    -s nap.time Sleep for given interval between writes (1.000 second) 
    -r std.dev Randomize the time (Gaussian around nap.time with std.dev) 
    -t   Write to standard output instead of file 
    -F format Printf format to use instead of %zu 

Also, es wurde das Schreiben in die Datei demo.txt bei einer mittleren Zeit von 1,5 Sekunden, mit einem Gaußschen Zufall Verteilung mit 0,5 Sekunden Standardabweichung. Deshalb gab es manchmal 2 EOF Messages zwischen aufeinanderfolgenden Zeilen des Ausgangs.

+0

Ich habe Änderungen nach Ihrem Code vorgenommen ... und das Ausführen dieser binären ...... manuell in dieser Datei schreiben, aber mein Programm ist nicht in der Lage um aktualisierte Daten zu lesen –

+0

Das ist traurig! Ich testete auf einem Mac mit macOS High Sierra 10.13.2, mit GCC 7.2.0 als Compiler. Ich bin zuversichtlich, dass es auf Linux und anderen Unix-basierten Plattformen funktionieren würde (obwohl ich diesen Code heute auf keiner anderen Plattform offiziell getestet habe). An welcher Plattform arbeiten Sie? Wie sieht dein modifizierter Code aus? (Sie könnten es bei Bedarf zur Frage hinzufügen - zerstören Sie nicht, was schon da ist.). Es ist ein bisschen schwer zu erraten, was Sie falsch gemacht haben, aber ich denke, Sie haben etwas falsch gemacht, oder Sie arbeiten an einer esoterischen Plattform, bei der das nicht funktioniert. –

+0

Ein Weg, auf dem Probleme auftreten können, ist, wenn das/die Programm (e), die in die Datei schreiben, es abschneiden und nicht immer anhängen. Es kann auch andere Wege geben. –

Verwandte Themen