2017-12-27 34 views
1

ログファイルがあります。そのログファイルを読み込み、EOFに達したら新しいデータを待つプログラムをCで作成します。 私のコードにtail -fを使用したくありません。 私は、次のコードを試みたが、それが動作していない:継続的に更新されたファイルを読み込み、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

[こちら](https://stackoverflow.com/questions/5474232/how-to-loop-through-only-active-file-descriptors-from-fd-set-result-from-select) – phyloflash

+0

ファイルの終わりに達したときにただちにスリープして再度読み込む必要はありません – Pras

答えて

4

あなたは、ファイルの第一の端部に到達すると、EOFのための入力ストリームフラグが設定されています。操作を再開する前にクリアする必要があります(clearerr(fp))。あなたは通常も眠るべきです。 (ストリームに関連付けられているファイルディスクリプタのlseek()を使用することは助けにはなりません。)

はここにあなたのコードに基づいてプログラムだ - 私は(特に良い名前ではありません)PATHの値を変更する必要がありました:

#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); 
} 

ファイルにデータを生成するプログラムがある場合は、そのファイルでテストできます。 dribbler

$ 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 
$ 

オプションがあります:私はことを行うプログラムdribbler持っているので、

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 

を、それはガウスランダムで、1.5秒の平均時間でファイルdemo.txtに書いていました標準偏差が0.5秒の分布。 これは、出力の連続する行の間に2つのメッセージが表示されることがあります。

+0

あなたのコードに従って変更しました...そしてそのバイナリを実行しています......そのファイルに手作業で書き込みます更新されたデータを読む –

+0

それは悲しいことです!私は、MacOS High Sierra 10.13.2を実行しているMacでGCC 7.2.0をコンパイラとして使ってテストしました。私はそれがLinuxや他のUnixベースのプラットフォーム上で動作すると確信しています(私はこのコードを今日他のどのプラットフォームでも正式にテストしていませんが)。どのプラットフォームで作業していますか?変更されたコードはどのように見えますか? (必要に応じて質問に追加することもできますが、すでにそこにあるものは破壊しないでください)。あなたが間違っていたことを推測するのはちょっと難しいですが、何か間違ったことをしたか、これがうまくいかない難解なプラットフォームで作業していると思います。 –

+0

あなたが問題に遭遇する一つの方法は、ファイルに書き込むプログラムが常に追加するのではなく、ファイルを切り捨てる場合です。他にも方法があるかもしれません。 –

関連する問題