Eu tenho um arquivo de log sendo gravado por outro processo que desejo observar nas alterações. Cada vez que ocorre uma alteração, eu gostaria de ler os novos dados para fazer algum processamento.
Qual é a melhor forma de fazer isso? Eu esperava que houvesse algum tipo de gancho na biblioteca do PyWin32. Eu encontrei a win32file.FindNextChangeNotification
função, mas não tenho idéia de como pedir para assistir a um arquivo específico.
Se alguém fez algo assim, ficaria muito grato em saber como ...
[Editar] Eu deveria ter mencionado que estava atrás de uma solução que não requer pesquisa.
[Editar] Maldições! Parece que isso não funciona em uma unidade de rede mapeada. Acho que o Windows não 'escuta' nenhuma atualização do arquivo da mesma forma que em um disco local.
strace
monitoramentowrite
para issoRespostas:
Você já consultou a documentação disponível em http://timgolden.me.uk/python/win32_how_do_i/watch_directory_for_changes.html ? Se você só precisa trabalhar no Windows, o segundo exemplo parece ser exatamente o que você deseja (se você trocar o caminho do diretório pelo do arquivo que deseja assistir).
Caso contrário, a pesquisa provavelmente será a única opção realmente independente de plataforma.
Nota: Eu não tentei nenhuma dessas soluções.
fonte
Você tentou usar o Watchdog ?
fonte
easy_install
? Verifica. Licença gratuita? Verifique . Resolve o problema nas grandes plataformas? Verifique . Eu apoio esta resposta. Nota: o exemplo na página do projeto não funciona imediatamente. Use aquele no github deles .Se a pesquisa for boa o suficiente para você, eu apenas observaria se o status do arquivo "horário modificado" muda. Para ler:
(Observe também que a solução de eventos de alteração nativa do Windows não funciona em todas as circunstâncias, por exemplo, em unidades de rede.)
fonte
if self._cached_stamp is not None
.Se você deseja uma solução multiplataforma, verifique QFileSystemWatcher . Aqui está um código de exemplo (não higienizado):
fonte
watchdog
pacote é a resposta certaPySide
para isso em vez dePyQt
para um uso tão pequeno.Ele não deve funcionar no Windows (talvez com o cygwin?), Mas para o usuário unix, você deve usar a chamada de sistema "fcntl". Aqui está um exemplo em Python. É basicamente o mesmo código se você precisar escrevê-lo em C (mesmos nomes de função)
fonte
Confira pyinotify .
O inotify substitui o dnotify (de uma resposta anterior) em linuxes mais recentes e permite o monitoramento no nível do arquivo e não no nível do diretório.
fonte
Bem, depois de um pouco de hacking no script de Tim Golden, tenho o seguinte, que parece funcionar muito bem:
Provavelmente, isso poderia resultar em uma verificação de erro muito maior, mas, simplesmente observando um arquivo de log e processando-o antes de enviá-lo para a tela, isso funciona bem.
Obrigado a todos por sua contribuição - ótimas coisas!
fonte
Para assistir a um único arquivo com sondagens e dependências mínimas, eis um exemplo completo, com base na resposta do Deestan (acima):
fonte
watch_file
e_cached_stamp
entrar em listas e iterá-las em um loop for. Realmente não escala bem para um grande número de arquivos emboracall_func_on_change()
será acionado na primeira execução delook()
, mas_cached_stamp
será atualizado, portanto, não será acionado novamente até que o valor dasos.stat(self.filename).st_mtime. _cached_stamp
alterações seja alterado._cached_stamp
no construtor se você não quercall_func_on_change()
ser chamado na primeira execuçãoself.call_func_on_change(self) def custom_action(): watcher = Watcher(watch_file, custom_action())
Mas isso não funcionou. A ação foi chamada apenas durante a primeira iteração: Arquivo alterado sim, alterado Arquivo alterado Arquivo alterado Arquivo alterado Ele começou a funcionar quando mantive * args e o chamei:watcher = Watcher(watch_file, custom_action)
luto para me perguntar por que?Verifique minha resposta para uma pergunta semelhante . Você pode tentar o mesmo loop no Python. Esta página sugere:
Veja também a pergunta tail () um arquivo com Python .
fonte
A solução mais simples para mim é usar a ferramenta watchdog, watchmedo
Em https://pypi.python.org/pypi/watchdog , agora tenho um processo que consulta os arquivos sql em um diretório e os executa, se necessário.
fonte
Bem, como você está usando Python, você pode simplesmente abrir um arquivo e continuar lendo as linhas dele.
Se a linha lida não estiver vazia , você a processa.
Pode estar faltando que não há problema em continuar ligando
readline
para o EOF. Apenas retornará uma string vazia neste caso. E quando algo é anexado ao arquivo de log, a leitura continuará de onde parou, conforme necessário.Se você estiver procurando por uma solução que use eventos ou uma biblioteca específica, especifique isso na sua pergunta. Caso contrário, acho que esta solução está bem.
fonte
Aqui está uma versão simplificada do código do Kender que parece fazer o mesmo truque e não importa o arquivo inteiro:
fonte
Essa é outra modificação do script de Tim Goldan, que roda em tipos unix e adiciona um observador simples para modificação de arquivo usando um dict (file => time).
use: WhateverName.py caminho_para_dir_para_watch
fonte
Como você pode ver no artigo de Tim Golden , apontado por Horst Gutmann , o WIN32 é relativamente complexo e observa diretórios, não um único arquivo.
Eu gostaria de sugerir que você analise o IronPython , que é uma implementação em python .NET . Com o IronPython, você pode usar toda a funcionalidade do .NET - incluindo
Que lida com arquivos únicos com uma interface de evento simples .
fonte
Este é um exemplo de verificação de alterações em um arquivo. Um que pode não ser a melhor maneira de fazê-lo, mas com certeza é um caminho curto.
Ferramenta útil para reiniciar o aplicativo quando alterações foram feitas na fonte. Eu fiz isso ao jogar com o pygame para que eu possa ver os efeitos imediatamente após o salvamento do arquivo.
Quando usado no pygame, certifique-se de que as coisas no loop 'while' sejam colocadas no loop do jogo, também conhecido como update ou o que for. Caso contrário, seu aplicativo ficará preso em um loop infinito e você não verá o jogo sendo atualizado.
Caso você queira o código de reinicialização que encontrei na web. Aqui está. (Não é relevante para a pergunta, embora possa ser útil)
Divirta-se fazendo elétrons fazerem o que você quer que eles façam.
fonte
.st_mtime
vez de.st_size
seria mais confiável e uma maneira igualmente curta de fazer isso, embora o OP tenha indicado que ele não queria fazê-lo por meio de pesquisas.fonte
Aqui está um exemplo voltado para assistir a arquivos de entrada que gravam não mais que uma linha por segundo, mas geralmente muito menos. O objetivo é anexar a última linha (gravação mais recente) ao arquivo de saída especificado. Copiei isso de um dos meus projetos e apaguei todas as linhas irrelevantes. Você precisará preencher ou alterar os símbolos ausentes.
Obviamente, a classe QMainWindow abrangente não é estritamente necessária, ou seja. você pode usar o QFileSystemWatcher sozinho.
fonte
Você também pode usar uma biblioteca simples chamada repyt , aqui está um exemplo:
fonte
Parece que ninguém postou fswatch . É um observador de sistema de arquivos multiplataforma. Basta instalar, executar e seguir as instruções.
Eu usei-o com programas python e golang e simplesmente funciona.
fonte
solução @ 4Oh4 relacionada - uma mudança suave para uma lista de arquivos para assistir;
fonte
A melhor e mais simples solução é usar o piggtail: https://pypi.python.org/pypi/pygtail
fonte
Não conheço nenhuma função específica do Windows. Você pode tentar obter o hash MD5 do arquivo a cada segundo / minuto / hora (depende da rapidez com que precisa) e compará-lo com o último hash. Quando difere, você sabe que o arquivo foi alterado e você leu as linhas mais recentes.
fonte
Eu tentaria algo assim.
O loop verifica se há uma (s) nova (s) linha (s) desde a última vez que o arquivo foi lido - se houver, ele foi lido e passado para a
functionThatAnalisesTheLine
função. Caso contrário, o script aguarda 1 segundo e tenta novamente o processo.fonte