Bir dosyayı değişiklikler için nasıl izlerim?


323

Değişiklikleri izlemek istediğim başka bir işlem tarafından yazılmış bir günlük dosyası var. Her değişiklik gerçekleştiğinde, üzerinde biraz işlem yapmak için yeni verileri okumak istiyorum.

Bunu yapmanın en iyi yolu nedir? PyWin32 kütüphanesinden bir çengel çengel olacağını umuyordum. win32file.FindNextChangeNotificationİşlevi buldum, ancak belirli bir dosyayı izlemesini nasıl isteyeceğimi bilmiyorum.

Birisi böyle bir şey yaptıysa, nasıl olduğunu duyduğuma minnettar olurum ...

[Düzenle] Ben yoklama gerektirmeyen bir çözüm sonrasında olduğunu belirtti gerekirdi.

[Düzenle] Lanetler! Bu, eşlenen bir ağ sürücüsü üzerinde çalışmaz gibi görünüyor. Tahmin ediyorum ki windows yerel bir diskte olduğu gibi dosyadaki herhangi bir güncellemeyi duymuyor.


1
Linux'ta bunun için straceizleme writeçağrıları kullanılabilir
test30

@ simao'nun cevabı python-watchdog kullanıyor. Python-Watchdog harika belgelere sahiptir -> işte mevcut çalışma dizinini izleyen minimal bir kod örneği sağlayan ["QuickStart"] belgelerine bir link.
Trevor Boyd Smith

Yanıtlar:


79

Zaten mevcut belgelere baktınız mı http://timgolden.me.uk/python/win32_how_do_i/watch_directory_for_changes.html ? Sadece Windows altında çalışmanız gerekiyorsa, 2. örnek tam olarak istediğiniz gibi görünüyor (dizinin yolunu izlemek istediğiniz dosyayla değiştirirseniz).

Aksi takdirde, oylama muhtemelen platformdan bağımsız tek seçenek olacaktır.

Not: Bu çözümlerden hiçbirini denemedim.


5
Bu yanıt Windows'a özgüdür, ancak bu soruna bazı platformlar arası çözümler de burada yayınlanmıştır.
Anderson Green

Bu süreç daha yavaşsa, o zaman c ++ gibi yerel bir dilde uygulanıyor mu?
user1767754

Atıfta bulunulabilecek kaynaklardan, ilgili içerikleri eklemek daha iyidir.
Trilarion

2
(1.) Bu cevabın sonunda güçlü bir feragatname ... "Bu çözümlerin hiçbirini denemedim". (2.) bu cevap aşağı yukarı bir "sadece bağlantı" cevabıdır (3.) cevap "yoklama" dan bahseder, ancak bundan sonra yararlı bir şey eklemez ... burada @ Deestan'ın cevabı yoklama hakkında bazı iyi bilgiler sağlar
Trevor Boyd Smith

283

Watchdog'u kullanmayı denedin mi?

Dosya sistemi olaylarını izlemek için Python API kütüphanesi ve kabuk yardımcı programları.

Dizin izleme artık çok kolay

  • Bir platformlar arası API.
  • Dizin değişikliklerine yanıt olarak komutları çalıştırmak için bir kabuk aracı.

Hızlı Başlangıç'ta basit bir örnekle hemen başlayın ...


56
İle yüklenebilir easy_installmi? Kontrol. Ücretsiz lisans? Kontrol edin . Büyük platformlarda sorunu çözüyor mu? Kontrol edin . Bu cevabı onaylıyorum. Sadece not: proje sayfalarındaki örnek kutudan çıkmaz. Kullanım onların üzerinde github birini yerine.
Inaimathi

6
Bekçi köpeği kullanıyoruz. QFileSystemWatcher'a geçebiliriz. Adil bir uyarı-watchdog iyi ama tüm platformlarda (şu anda) mükemmel olmaktan uzak. Her işletim sisteminin kendine özgü özellikleri vardır. Bu yüzden, mükemmel hale getirmeye adanmadıkça saçınızı çekeceksiniz. Eğer sadece 10 dosya izlemek istiyorsanız, anket yapardım. İşletim sistemi disk önbelleği çok olgun ve Watchdog zaten yoklama API'leri içerir. Esas olarak büyük klasör yapılarını IMHO izlemek için.
SilentSteel

3
Bekçi köpeği ile yaptığım tek sıkıntı, birçok bağımlılığı olduğu. Tabii ki PyQt'tan daha az, ama işe yaramaz ve asgari, en iyi uygulama gibi hissetmez, bir iş için doğru çözüm yapar.
AndreasT

1
@Denfromufa burada doğru mu? Watchdog dosyaları gerçekten kilitliyor mu, bu yüzden onları izlerken watchdog için aynı anda düzenlenemezler mi? Buna tamamen inanamıyorum, tamamen işe yaramaz olurdu.
Michel Müller

1
@ MichelMüller Bu örneği yeni kontrol ettim (aşağıdaki bağlantıya bakın) ve işe yarıyor! daha önce neyin yanlış olduğundan emin değilim, ama bu cevap herhangi bir örnek vermiyor. stackoverflow.com/a/18599427/2230844
denfromufa

92

Oylama sizin için yeterince iyiyse, "değiştirilme zamanı" dosya durumunun değişip değişmediğini izlerim. Okumak için:

os.stat(filename).st_mtime

(Ayrıca Windows yerel değişiklik olay çözümünün, örneğin ağ sürücülerinde her durumda çalışmadığını unutmayın.)

import os

class Monkey(object):
    def __init__(self):
        self._cached_stamp = 0
        self.filename = '/path/to/file'

    def ook(self):
        stamp = os.stat(self.filename).st_mtime
        if stamp != self._cached_stamp:
            self._cached_stamp = stamp
            # File has changed, so do something...

1
Bunu belirli aralıklarla nasıl yapabilirsiniz?
dopatraman

1
@dopatraman Bunu, True: try: time.sleep (1) pub.watch () dışında KeyboardInterrupt: print ('\ nDone') dışında : yazdır (Kullanılmayan hata: {sys.exc_info () [0]} ') `
Vlad Bezden

Harika basit bir çözüm! İlk çalıştırmada değiştirildi dosyayı raporlama onu tutmak için bir onay eklendi: if self._cached_stamp is not None.
Noumenon

50

Çok platformlu bir çözüm istiyorsanız, QFileSystemWatcher'ı kontrol edin . Burada bir örnek kod (sterilize edilmemiş):

from PyQt4 import QtCore

@QtCore.pyqtSlot(str)
def directory_changed(path):
    print('Directory Changed!!!')

@QtCore.pyqtSlot(str)
def file_changed(path):
    print('File Changed!!!')

fs_watcher = QtCore.QFileSystemWatcher(['/path/to/files_1', '/path/to/files_2', '/path/to/files_3'])

fs_watcher.connect(fs_watcher, QtCore.SIGNAL('directoryChanged(QString)'), directory_changed)
fs_watcher.connect(fs_watcher, QtCore.SIGNAL('fileChanged(QString)'), file_changed)

6
Ben onlar a) Win32's FileSystemwatcher nesnesine güvenir ve taşınamaz veya b) dosya (bu performans için kötü ve ölçek değil) için anket göz önüne alındığında, bu büyük olasılıkla demet en iyi cevap olduğunu düşünüyorum. Python, kullandığınız tek şey QFileSystemWatcher sınıfıysa PyQt büyük bir bağımlılık olduğu için bu tesisin yerleşik olmaması üzücü.
CadentOrange

4
Bu çözümü seviyorum. Çalışması için bir QApplication örneğine ihtiyacınız olduğunu belirtmek istedim, "app = QtGui.QApplication (sys.argv)" 'ı hemen ithalat altına ve sonra "app.exec_ ()" sinyal bağlantılarından sonra ekledim.
spencewah

Sadece bunu bir Linux kutusunda test ediyorum, directory_changed yönteminin çağrıldığını görüyorum, ancak file_changed.
Ken Kinder

Eğer PyQt bağımlılık gibi yapmazsam @CadentOrange, paket doğru cevapwatchdog
Mike Pennington

neden böyle küçük bir kullanım PySideyerine bunun PyQtiçin kullanmıyorsunuz.
Ciasto piekarz

29

Windows üzerinde çalışmamalıdır (belki cygwin ile?), Ancak unix kullanıcısı için "fcntl" sistem çağrısını kullanmalısınız. İşte Python'da bir örnek. C ile yazmanız gerekiyorsa çoğunlukla aynı koddur (aynı işlev adları)

import time
import fcntl
import os
import signal

FNAME = "/HOME/TOTO/FILETOWATCH"

def handler(signum, frame):
    print "File %s modified" % (FNAME,)

signal.signal(signal.SIGIO, handler)
fd = os.open(FNAME,  os.O_RDONLY)
fcntl.fcntl(fd, fcntl.F_SETSIG, 0)
fcntl.fcntl(fd, fcntl.F_NOTIFY,
            fcntl.DN_MODIFY | fcntl.DN_CREATE | fcntl.DN_MULTISHOT)

while True:
    time.sleep(10000)

3
Bir ext4 dosya sisteminde (Ubuntu 10.04'te) Linux çekirdeği 2.6.31 ile bir cazibe gibi çalışır, ancak sadece dizinler için - bir dosyayla kullanırsam bir dizin değil "IOError oluşturur".
David Underhill

1
HARİKA! Aynı benim için, sadece dizin için çalışır ve bu dizindeki dosyaları izlemek. Ancak alt dizinlerdeki değiştirilmiş dosyalar için çalışmaz, bu yüzden düşünce alt dizinlerini yürümeniz ve hepsini izlemeniz gerekir. (ya da bunu yapmanın daha iyi bir yolu var mı?)
lfagundes

20

Pyinotify'a göz atın .

inotify, daha yeni linux'larda dnotify'ın (önceki bir yanıttan) yerini alır ve dizin düzeyinde izleme yerine dosya düzeyinde izin verir.


5
Bu cevaba bir damper koymak değil, ama bu makaleyi okuduktan sonra, bunun düşünce kadar cazip bir çözüm olmayabileceğini söyleyebilirim. serpentine.com/blog/2008/01/04/why-you-should-not-use-pyinotify
NuclearPeon

1
pyinotify'ın çok epikonik kod tabanından bellek tüketimine kadar birçok dezavantajı vardır. Diğer seçenekleri aramak daha iyi ..
Tyto

13

Tim Golden'un senaryosunu hackledikten sonra, oldukça iyi çalışan aşağıdakilere sahibim:

import os

import win32file
import win32con

path_to_watch = "." # look at the current directory
file_to_watch = "test.txt" # look for changes to a file called test.txt

def ProcessNewData( newData ):
    print "Text added: %s"%newData

# Set up the bits we'll need for output
ACTIONS = {
  1 : "Created",
  2 : "Deleted",
  3 : "Updated",
  4 : "Renamed from something",
  5 : "Renamed to something"
}
FILE_LIST_DIRECTORY = 0x0001
hDir = win32file.CreateFile (
  path_to_watch,
  FILE_LIST_DIRECTORY,
  win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
  None,
  win32con.OPEN_EXISTING,
  win32con.FILE_FLAG_BACKUP_SEMANTICS,
  None
)

# Open the file we're interested in
a = open(file_to_watch, "r")

# Throw away any exising log data
a.read()

# Wait for new data and call ProcessNewData for each new chunk that's written
while 1:
  # Wait for a change to occur
  results = win32file.ReadDirectoryChangesW (
    hDir,
    1024,
    False,
    win32con.FILE_NOTIFY_CHANGE_LAST_WRITE,
    None,
    None
  )

  # For each change, check to see if it's updating the file we're interested in
  for action, file in results:
    full_filename = os.path.join (path_to_watch, file)
    #print file, ACTIONS.get (action, "Unknown")
    if file == file_to_watch:
        newText = a.read()
        if newText != "":
            ProcessNewData( newText )

Muhtemelen bir yük daha fazla hata kontrolü ile yapabilirdi, ama sadece bir günlük dosyasını izlemek ve ekrana tükürmeden önce üzerinde bazı işlemler yapmak için, bu iyi çalışıyor.

Katkılarınız için herkese teşekkürler - harika şeyler!


10

Yoklama ve minimum bağımlılık içeren tek bir dosyayı izlemek için, Deestan'ın cevabına dayanan (yukarıda) tam bir örnek :

import os
import sys 
import time

class Watcher(object):
    running = True
    refresh_delay_secs = 1

    # Constructor
    def __init__(self, watch_file, call_func_on_change=None, *args, **kwargs):
        self._cached_stamp = 0
        self.filename = watch_file
        self.call_func_on_change = call_func_on_change
        self.args = args
        self.kwargs = kwargs

    # Look for changes
    def look(self):
        stamp = os.stat(self.filename).st_mtime
        if stamp != self._cached_stamp:
            self._cached_stamp = stamp
            # File has changed, so do something...
            print('File changed')
            if self.call_func_on_change is not None:
                self.call_func_on_change(*self.args, **self.kwargs)

    # Keep watching in a loop        
    def watch(self):
        while self.running: 
            try: 
                # Look for changes
                time.sleep(self.refresh_delay_secs) 
                self.look() 
            except KeyboardInterrupt: 
                print('\nDone') 
                break 
            except FileNotFoundError:
                # Action on file not found
                pass
            except: 
                print('Unhandled error: %s' % sys.exc_info()[0])

# Call this function each time a change happens
def custom_action(text):
    print(text)

watch_file = 'my_file.txt'

# watcher = Watcher(watch_file)  # simple
watcher = Watcher(watch_file, custom_action, text='yes, changed')  # also call custom action function
watcher.watch()  # start the watch going

2
Listeler oluşturabilir watch_fileve _cached_stamplisteler oluşturabilir ve for döngüsünde yineleyebilirsiniz. Çok sayıda dosyaya gerçekten iyi ölçeklenmiyor
4Oh4

Bu, her çalıştırıldığında eylemi tetiklemez mi? _cached_stamp 0 olarak ayarlanır ve os.stat (selffilename) .st_mtime ile karşılaştırılır. _cached_stamp yapıcıda os.stat (self.filename) .st_mtime olarak ayarlanmalıdır, hayır?
Seanonymous

1
call_func_on_change()ilk çalıştırıldığında tetiklenir look(), ancak daha sonra _cached_stampgüncellenir, bu nedenle os.stat(self.filename).st_mtime. _cached_stampdeğişikliklerin değeri kadar tekrar tetiklenmez .
4Oh4

1
İlk çalıştırmada çağrılmak _cached_stampistemiyorsanız yapıcıdaki değerini ayarlayabilirsinizcall_func_on_change()
4Oh4

Komut dosyanızı dosya değişikliği ile ilgili bazı işlevleri çağırmak için kullandım. Benim fonksiyonum sizinkinden farklı bir argüman almıyor. Çalışmasını sağlamak için * args, ** kwargs'ı kaldırmam gerektiğini düşündüm. Görünüşe göre (sadece değişikliklerle çizgiler koydum): self.call_func_on_change(self) def custom_action(): watcher = Watcher(watch_file, custom_action())Ama bu işe yaramadı. Eylem yalnızca ilk yineleme sırasında çağrıldı: Dosya değişti evet, değişti Dosya değişti Dosya değişti Dosya değişti * Args tuttuğumda çalıştım ve onu çağırdım: watcher = Watcher(watch_file, custom_action)Nedenini merak ediyorum?
zwornik

7

Kontrol Cevabımı a benzer bir soru . Aynı döngüyü Python'da deneyebilirsiniz. Bu sayfa şunları önerir:

import time

while 1:
    where = file.tell()
    line = file.readline()
    if not line:
        time.sleep(1)
        file.seek(where)
    else:
        print line, # already has newline

Ayrıca Python ile bir dosya tail () sorusuna bakın .


Sys.stdout.write (satır) yapabilirsiniz. Dosya kesilirse kodunuz çalışmaz. Python yerleşik fonksiyon dosyasına () sahiptir.
jfs

Kodunuzun değiştirilmiş bir sürümünü yayınladım. Sizin için işe yararsa cevabınıza dahil edebilirsiniz.
jfs

7

Benim için en basit çözüm watchdog'un watchmedo aracını kullanmak

Gönderen https://pypi.python.org/pypi/watchdog Şimdi bir yol olmasını sql bir dizindeki dosya ve yürütür onları gerekirse kadar görünüyor.

watchmedo shell-command \
--patterns="*.sql" \
--recursive \
--command='~/Desktop/load_files_into_mysql_database.sh' \
.

6

Python kullandığınız için, sadece bir dosya açabilir ve ondan satır okumaya devam edebilirsiniz.

f = open('file.log')

Satır okuması boş değilse, işlersiniz .

line = f.readline()
if line:
    // Do what you want with the line

Aramaya devam etmenin bir sakıncası olmayabilir readlineEOF'da devam etmenin uygun olmadığını görebilirsiniz. Bu durumda boş bir dize döndürmeye devam edecektir. Ve günlük dosyasına bir şey eklendiğinde, okuma istediğiniz yerde durduğu yerden devam edecektir.

Olayları veya belirli bir kütüphaneyi kullanan bir çözüm arıyorsanız, lütfen sorunuzda bunu belirtin. Aksi takdirde, bu çözümün iyi olduğunu düşünüyorum.


6

İşte Kendisi kodunun aynı hile yapıyormuş gibi görünen ve tüm dosyayı içe aktarmayan basitleştirilmiş bir versiyonu:

# Check file for new data.

import time

f = open(r'c:\temp\test.txt', 'r')

while True:

    line = f.readline()
    if not line:
        time.sleep(1)
        print 'Nothing New'
    else:
        print 'Call Function: ', line

6

Bu, Tim Goldan'ın komut dosyasının unix türlerinde çalışan ve bir dict (dosya => zaman) kullanarak dosya değişikliği için basit bir izleyici ekleyen başka bir modifikasyonudur.

kullanım: whateverName.py path_to_dir_to_watch

#!/usr/bin/env python

import os, sys, time

def files_to_timestamp(path):
    files = [os.path.join(path, f) for f in os.listdir(path)]
    return dict ([(f, os.path.getmtime(f)) for f in files])

if __name__ == "__main__":

    path_to_watch = sys.argv[1]
    print('Watching {}..'.format(path_to_watch))

    before = files_to_timestamp(path_to_watch)

    while 1:
        time.sleep (2)
        after = files_to_timestamp(path_to_watch)

        added = [f for f in after.keys() if not f in before.keys()]
        removed = [f for f in before.keys() if not f in after.keys()]
        modified = []

        for f in before.keys():
            if not f in removed:
                if os.path.getmtime(f) != before.get(f):
                    modified.append(f)

        if added: print('Added: {}'.format(', '.join(added)))
        if removed: print('Removed: {}'.format(', '.join(removed)))
        if modified: print('Modified: {}'.format(', '.join(modified)))

        before = after

Python3'ü desteklemek için güncellendi
ronedg

4

Tim Golden'ın Horst Gutmann'ın işaret ettiği makalesinde görebileceğiniz gibi , WIN32 nispeten karmaşıktır ve tek bir dosya değil, dizinleri izler.

Bir .NET python uygulaması olan IronPython'a bakmanızı öneririm . IronPython ile tüm .NET işlevlerini kullanabilirsiniz.

System.IO.FileSystemWatcher

Basit bir Olay arayüzü ile tek dosyaları işler .


@Ciasto çünkü o zaman temel bir Python kurulumu yerine Demir Python'u kullanmak zorundasınız.
Jon Cage

1

Bu, dosyada değişiklik olup olmadığını kontrol etmenin bir örneğidir. Bunu yapmanın en iyi yolu olmayabilir, ama kesinlikle kısa bir yol.

Kaynakta değişiklikler yapıldığında uygulamayı yeniden başlatmak için kullanışlı bir araç. Bunu pygame ile oynarken yaptım, böylece efektler dosya kaydettikten hemen sonra gerçekleşiyor.

Pygame'de kullanıldığında, 'while' döngüsündeki öğelerin oyun döngünüze aka güncelleme ya da başka bir şekilde yerleştirildiğinden emin olun. Aksi takdirde uygulamanız sonsuz bir döngüde kalır ve oyun güncellemenizi görmezsiniz.

file_size_stored = os.stat('neuron.py').st_size

  while True:
    try:
      file_size_current = os.stat('neuron.py').st_size
      if file_size_stored != file_size_current:
        restart_program()
    except: 
      pass

Web'de bulduğum yeniden başlatma kodunu istemeniz durumunda. İşte burada. (Soruyla ilgili değildir, ancak kullanışlı olabilir)

def restart_program(): #restart application
    python = sys.executable
    os.execl(python, python, * sys.argv)

Yapmalarını istediğiniz elektronları yaparak eğlenin.


OP .st_mtimeyerine kullanmak .st_sizedaha güvenilir ve bunu yapmanın eşit derecede kısa bir yolu gibi görünüyor , ancak OP anket yoluyla yapmak istemediğini belirtti.
martineau

1
ACTIONS = {
  1 : "Created",
  2 : "Deleted",
  3 : "Updated",
  4 : "Renamed from something",
  5 : "Renamed to something"
}
FILE_LIST_DIRECTORY = 0x0001

class myThread (threading.Thread):
    def __init__(self, threadID, fileName, directory, origin):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.fileName = fileName
        self.daemon = True
        self.dir = directory
        self.originalFile = origin
    def run(self):
        startMonitor(self.fileName, self.dir, self.originalFile)

def startMonitor(fileMonitoring,dirPath,originalFile):
    hDir = win32file.CreateFile (
        dirPath,
        FILE_LIST_DIRECTORY,
        win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
        None,
        win32con.OPEN_EXISTING,
        win32con.FILE_FLAG_BACKUP_SEMANTICS,
        None
    )
    # Wait for new data and call ProcessNewData for each new chunk that's
    # written
    while 1:
        # Wait for a change to occur
        results = win32file.ReadDirectoryChangesW (
            hDir,
            1024,
            False,
            win32con.FILE_NOTIFY_CHANGE_LAST_WRITE,
            None,
            None
        )
        # For each change, check to see if it's updating the file we're
        # interested in
        for action, file_M in results:
            full_filename = os.path.join (dirPath, file_M)
            #print file, ACTIONS.get (action, "Unknown")
            if len(full_filename) == len(fileMonitoring) and action == 3:
                #copy to main file
                ...

1

Aşağıda, saniyede birden fazla satır yazamayan, genellikle çok daha az yazan giriş dosyalarını izlemeye yönelik bir örnek verilmiştir. Amaç, son satırı (en son yazma) belirtilen çıktı dosyasına eklemektir. Bunu projelerimden birinden kopyaladım ve ilgisiz tüm satırları sildim. Eksik sembolleri doldurmanız veya değiştirmeniz gerekir.

from PyQt5.QtCore import QFileSystemWatcher, QSettings, QThread
from ui_main_window import Ui_MainWindow   # Qt Creator gen'd 

class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        Ui_MainWindow.__init__(self)
        self._fileWatcher = QFileSystemWatcher()
        self._fileWatcher.fileChanged.connect(self.fileChanged)

    def fileChanged(self, filepath):
        QThread.msleep(300)    # Reqd on some machines, give chance for write to complete
        # ^^ About to test this, may need more sophisticated solution
        with open(filepath) as file:
            lastLine = list(file)[-1]
        destPath = self._filemap[filepath]['dest file']
        with open(destPath, 'a') as out_file:               # a= append
            out_file.writelines([lastLine])

Tabii ki, kapsayan QMainWindow sınıfı kesinlikle gerekli değildir, yani. yalnızca QFileSystemWatcher'ı kullanabilirsiniz.


0

Ayrıca repyt adında basit bir kütüphane de kullanabilirsiniz , işte bir örnek:

repyt ./app.py

0

Hiç kimse fswatch yayınlamadı . Bir platformlar arası dosya sistemi izleyicisidir. Sadece kurun, çalıştırın ve komutları izleyin.

Python ve golang programlarıyla kullandım ve işe yarıyor.


0

related @ 4Oh4 çözümü izlenecek dosyaların listesi için yumuşak bir değişiklik;

import os
import sys
import time

class Watcher(object):
    running = True
    refresh_delay_secs = 1

    # Constructor
    def __init__(self, watch_files, call_func_on_change=None, *args, **kwargs):
        self._cached_stamp = 0
        self._cached_stamp_files = {}
        self.filenames = watch_files
        self.call_func_on_change = call_func_on_change
        self.args = args
        self.kwargs = kwargs

    # Look for changes
    def look(self):
        for file in self.filenames:
            stamp = os.stat(file).st_mtime
            if not file in self._cached_stamp_files:
                self._cached_stamp_files[file] = 0
            if stamp != self._cached_stamp_files[file]:
                self._cached_stamp_files[file] = stamp
                # File has changed, so do something...
                file_to_read = open(file, 'r')
                value = file_to_read.read()
                print("value from file", value)
                file_to_read.seek(0)
                if self.call_func_on_change is not None:
                    self.call_func_on_change(*self.args, **self.kwargs)

    # Keep watching in a loop
    def watch(self):
        while self.running:
            try:
                # Look for changes
                time.sleep(self.refresh_delay_secs)
                self.look()
            except KeyboardInterrupt:
                print('\nDone')
                break
            except FileNotFoundError:
                # Action on file not found
                pass
            except Exception as e:
                print(e)
                print('Unhandled error: %s' % sys.exc_info()[0])

# Call this function each time a change happens
def custom_action(text):
    print(text)
    # pass

watch_files = ['/Users/mexekanez/my_file.txt', '/Users/mexekanez/my_file1.txt']

# watcher = Watcher(watch_file)  # simple



if __name__ == "__main__":
    watcher = Watcher(watch_files, custom_action, text='yes, changed')  # also call custom action function
    watcher.watch()  # start the watch going


-2

Windows'a özgü bir işlev bilmiyorum. Her saniye / dakika / saatte bir MD5 karmasını almayı deneyebilirsiniz (ne kadar hızlı ihtiyacınıza bağlı olarak) ve son kareyle karşılaştırabilirsiniz. Farklı olduğunda dosyanın değiştirildiğini ve en yeni satırları okuduğunuzu bilirsiniz.


-6

Böyle bir şey denerdim.

    try:
            f = open(filePath)
    except IOError:
            print "No such file: %s" % filePath
            raw_input("Press Enter to close window")
    try:
            lines = f.readlines()
            while True:
                    line = f.readline()
                    try:
                            if not line:
                                    time.sleep(1)
                            else:
                                    functionThatAnalisesTheLine(line)
                    except Exception, e:
                            # handle the exception somehow (for example, log the trace) and raise the same exception again
                            raw_input("Press Enter to close window")
                            raise e
    finally:
            f.close()

Döngü, son dosya okunduğundan beri yeni satır (lar) olup olmadığını kontrol eder - eğer varsa, okunur ve functionThatAnalisesTheLineişleve iletilir . Değilse, komut dosyası 1 saniye bekler ve işlemi yeniden dener.


4
-1: Dosya 100 MB büyüklüğünde olduğunda, dosyayı açmak ve satırları okumak iyi bir fikir değildir. 1000 dosyayı izlemek istediğinizde kötü olacak her dosya için de çalıştırmanız gerekir.
Jon Cage

1
Gerçekten mi? Dosya değişiklik için açılsın mı?
Farsheed
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.