в реалтайме обнаруживать новые дозаписи в файл и реагировать.
как это лучше реализовать..?
во FreeBSD man kqueue
>в реалтайме обнаруживать новые дозаписи в файл и реагировать.
>как это лучше реализовать..?Если на перл то http://search.cpan.org на предмет ключа Tail.
В общем случае, если скорость реакции на обновление не сильно критична, можно сделать так:
Запоминаем позицию конца файла (tell()) и время изменения, между делом или периодически проверяем время модификации (stat()), если время больше запомненного - читаем данные от сохраненной позации (seek()), далее все сначала.
Если время реакции очень критично, то можно держать файл открытым и через select() улавливать приход новых данных, но дополнительно придется задуматься над тем что файл может быть удален или обрезан.
>select() улавливать приход новых данных, но дополнительно придется задуматься над тем
>что файл может быть удален или обрезан.
отлично.
спасибо.
>в реалтайме обнаруживать новые дозаписи в файл и реагировать.
>как это лучше реализовать..?Можно на место файла трубу (pipe) поместить с тем же именем и просто читать из нее. При условии, что такой вариант уместен в вашем случае.
Я, например, так сделал редиректор access.log в постгресовую базу - реализовав тем самым функциональность небезызвестного SARG-a. Всего за пару часов.
>>в реалтайме обнаруживать новые дозаписи в файл и реагировать.
>>как это лучше реализовать..?
>
>Можно на место файла трубу (pipe) поместить с тем же именем и
>просто читать из нее. При условии, что такой вариант уместен в
>вашем случае.
>
>Я, например, так сделал редиректор access.log в постгресовую базу - реализовав тем
>самым функциональность небезызвестного SARG-a. Всего за пару часов.
неподходит, ибо файл тоже нужен.у меня другой вопрос появился
написал код с select()но грузит проц на 98%
#include <sys/types.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>#define BUFFSIZE 1024
#define LOGFILE "access.log"
void get_new_data (int stream, char *buffer, int size)
{
int n = 1;
memset (buffer, 0, size);
do
{
n = read (stream, buffer, size);
if (n > 0)
printf ("%s", buffer);
} while ( n > 0 );
}int main (int argc, char **argv)
{
char *buffer;
int file;
fd_set f;
struct timeval tv;buffer = (char *) malloc (BUFFSIZE);
file = open (LOGFILE, O_RDONLY);
if (file < 0)
{
perror ("open");
return 1;
}
get_new_data (file, buffer, BUFFSIZE);
while (1)
{
FD_ZERO (&f);
FD_SET (file, &f);
tv.tv_sec = 5;
tv.tv_sec = 0;
if (select (FD_SETSIZE, NULL, NULL, NULL, &tv))
{
if (FD_ISSET (file, &f))
get_new_data (file, buffer, BUFFSIZE);
}
}close(file);
free (buffer);
}как подправить?
>>>в реалтайме обнаруживать новые дозаписи в файл и реагировать.
>>>как это лучше реализовать..?
>>
>>Можно на место файла трубу (pipe) поместить с тем же именем и
>>просто читать из нее. При условии, что такой вариант уместен в
>>вашем случае.
[...]
>неподходит, ибо файл тоже нужен.
>
>у меня другой вопрос появился
>написал код с select()но грузит проц на 98%Беда в том, что файл, как это ни печально, отличается от трубы. Именно в
данном случае. В трубе состояние "конец файла" возникает лишь когда
закроется пишущий конец; с файлом же это случается как только читатель
доходит до конца наличных данных. С этого момента select возвращается
сразу (т.е. можно читать без блокировки), после чего read -- сразу, без
блокировки! -- возврашается, прочтя 0 байт.В последних версиях ядра (начиная с 2.4.?) есть fcntl F_NOTIFY, выставив
который, можно получать сигналы об изменениях в директории. Поднимите бит
DN_MODIFY и убеждайтесь (через [f]stat), что речь идет о нужном файле.Единственный portable способ (как это сделано в gnu tail) -- убедившись,
что read вернул 0, поспать немножко.