파일이 변경되었는지 어떻게 확인합니까?


323

변경 사항을보고 싶은 다른 프로세스에서 로그 파일을 작성하고 있습니다. 변경이 발생할 때마다 처리를 위해 새 데이터를 읽고 싶습니다.

가장 좋은 방법은 무엇입니까? PyWin32 라이브러리에서 일종의 후크가 있기를 바랐습니다. win32file.FindNextChangeNotification함수를 찾았 지만 특정 파일을 보도록 요청하는 방법을 모릅니다.

누군가 이와 같은 일을한다면 정말 어떻게 들었는지 감사하게 생각합니다.

[편집] 필자는 폴링이 필요없는 솔루션을 따르고 있다고 언급 했어야합니다.

[편집] 저주! 매핑 된 네트워크 드라이브에서는 작동하지 않는 것 같습니다. Windows가 로컬 디스크에서와 같은 방식으로 파일에 대한 업데이트를 듣지 않는다고 생각합니다.


1
리눅스에 하나가 사용할 수있는 strace모니터링 write이 요구를
test30

@simao의 답변 은 python-watchdog을 사용합니다. Python-Watchdog에는 훌륭한 문서가 있습니다. 여기에는 현재 작업 디렉토리를 감시하는 최소한의 코드 예제를 제공하는 [ "QuickStart"] 문서에 대한 링크가 있습니다.
Trevor Boyd Smith

답변:


79

http://timgolden.me.uk/python/win32_how_do_i/watch_directory_for_changes.html 에있는 설명서를 이미 보셨습니까 ? Windows에서만 작동 해야하는 경우 두 번째 예는 정확히 원하는 것 같습니다 (보고 싶은 파일 중 하나와 디렉토리 경로를 교환하는 경우).

그렇지 않으면, 폴링은 아마도 플랫폼에 독립적 인 유일한 옵션 일 것입니다.

참고 : 나는 이러한 해결책을 시도하지 않았습니다.


5
이 답변은 Windows 전용이지만이 문제에 대한 일부 플랫폼 간 솔루션이 여기에 게시 된 것으로 보입니다.
Anderson Green

이 프로세스가 느리다면 c ++과 같은 모국어로 구현하는 벤치 마크가 있습니까?
user1767754

인용 된 출처의 관련 콘텐츠는 오래 될 수 있으므로 삽입하는 것이 좋습니다.
Trilarion

2
(1.)이 답변의 끝에는 "면제를 시도하지 않았습니다"라는 강력한 면책 조항이 있습니다. (2.)이 답변은 "링크 전용"답변입니다 (3.) 답변에 "폴링"이 언급되어 있지만 그 이후에는 도움이 될만한 내용이 없습니다 ... @Deestan의 답변 이 설문 조사에 대한 좋은 정보를 제공합니다
Trevor Boyd Smith

283

워치 독 을 사용해 보셨습니까 ?

파일 시스템 이벤트를 모니터링하는 Python API 라이브러리 및 셸 유틸리티

간편한 디렉토리 모니터링

  • 크로스 플랫폼 API.
  • 디렉토리 변경에 대한 응답으로 명령을 실행하는 쉘 도구입니다.

빠른 시작 의 간단한 예제로 빠르게 시작하십시오 ...


56
easy_install?로 설치 가능 검사. 무료 라이센스? 확인하십시오 . 큰 플랫폼에서 문제를 해결 하시겠습니까? 확인하십시오 . 이 답변을 보증합니다. 참고 : 프로젝트 페이지예제 는 기본적으로 작동하지 않습니다. 대신 github에있는 것을 사용하십시오 .
Inaimathi

6
우리는 워치 독을 사용합니다. QFileSystemWatcher로 전환 할 수 있습니다. 공정한 경고-감독은 좋지만 현재 모든 플랫폼에서 완벽하지는 않습니다. 각 OS에는 고유 한 특성이 있습니다. 당신이 그것을 완벽하게 만들기 위해 최선을 다하지 않는 한, 그래서 당신은 당신의 머리를 당겨 것입니다. 10 개 정도의 파일 만 보려고한다면 설문 조사를합니다. OS 디스크 캐싱은 매우 성숙하고 Watchdog은 API 폴링과 관련이 있습니다. IMHO의 거대한 폴더 구조를 주로 볼 수 있습니다.
SilentSteel

3
워치 독에 대한 한 가지 단점은 많은 의존성이 있다는 것입니다. 물론 PyQt보다 적지 만 최소한의 모범 사례 인 일대일 및 올바른 솔루션처럼 작동하지 않습니다.
AndreasT

1
@denfromufa가 여기에 맞습니까? 워치 독은 실제로 파일을 잠그므로 워치 독이 파일을 보면서 동시에 편집 할 수 없습니까? 나는 완전히 쓸모가 없을 것이라고 믿을 수 없다.
Michel Müller

1
@ MichelMüller 방금이 예제를 확인했으며 (아래 링크 참조) 작동합니다! 이전에 무엇이 잘못되었는지 확실하지 않지만이 답변은 예를 제공하지 않습니다. stackoverflow.com/a/18599427/2230844
denfromufa 0시 24 분

92

폴링이 충분하다면 "수정 된 시간"파일 통계가 변경되는지 확인합니다. 그것을 읽으려면 :

os.stat(filename).st_mtime

또한 Windows 기본 변경 이벤트 솔루션은 네트워크 드라이브와 같은 모든 상황에서 작동하지 않습니다.

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
어떻게 간격을두고이 작업을 수행 할 수 있습니까?
dopatraman 2016 년

1
@dopatraman 다음은 간격으로 이것을 수행하는 방법입니다.`import sys import time pub = Monkey () True : try : time.sleep (1) pub.watch () KeyboardInterrupt를 제외하고 : print ( '\ nDone') break except : print (f '처리되지 않은 오류 : {sys.exc_info () [0]}')`
Vlad Bezden

훌륭한 간단한 해결책! 첫 실행시 변경된 파일을보고하지 못하도록 검사를 추가했습니다 if self._cached_stamp is not None.
누 메논

50

멀티 플랫폼 솔루션을 원하면 QFileSystemWatcher 를 확인 하십시오 . 다음은 예제 코드입니다 (위생되지 않음).

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
나는 이것이 a) Win32의 FileSystemwatcher 객체에 의존하고 이식 할 수 없거나 b) 파일에 대한 폴링 (성능이 나쁘고 확장되지 않음)을 고려할 때 아마도 가장 좋은 대답이라고 생각합니다. 사용하는 모든 것이 QFileSystemWatcher 클래스 인 경우 PyQt가 큰 의존성이므로 Python에는이 기능이 내장되어 있지 않습니다.
CadentOrange

4
나는이 해결책을 좋아한다. 작동하려면 QApplication 인스턴스가 필요하다는 점을 지적하고 싶습니다. 가져 오기 바로 아래에 "app = QtGui.QApplication (sys.argv)"를 추가 한 다음 신호 연결 후 "app.exec_ ()"를 추가했습니다.
spencewah

Linux 상자에서 이것을 테스트하면 directory_changed 메소드가 호출되지만 file_changed는 호출되지 않습니다.
Ken Kinder

당신이 PyQt는 의존성 마음에 들지 않으면 @CadentOrange, 패키지는 정답이다watchdog
마이크 페닝 턴

그런 작은 용도 PySide대신에 그것을 사용하지 않는 이유는 무엇입니까? PyQt
Ciasto piekarz

29

Windows에서는 작동하지 않지만 (cygwin? 일 수 있음) UNIX 사용자의 경우 "fcntl"시스템 호출을 사용해야합니다. 다음은 Python의 예입니다. C로 작성 해야하는 경우 대부분 동일한 코드입니다 (동일한 함수 이름)

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
ext4 파일 시스템 (Ubuntu 10.04)에서 Linux 커널 2.6.31의 매력처럼 작동하지만 디렉토리에만 해당됩니다. 파일과 함께 사용하면 "디렉토리가 아닌"IOError가 발생합니다.
David Underhill

1
큰! 나에게도 동일하며 디렉토리에서만 작동 하며이 디렉토리의 파일을 감시합니다. 그러나 하위 디렉토리의 수정 된 파일에는 작동하지 않으므로 하위 디렉토리를 살펴보고 모든 디렉토리를 감시해야하는 것처럼 보입니다. (또는 이것을 수행하는 더 좋은 방법이 있습니까?)
lfagundes

20

pyinotify를 확인하십시오 .

inotify는 최신 리눅스에서 dnotify를 대체하고 (디렉토리 레벨 모니터링보다는 파일 레벨을 허용합니다).


5
이 답변에 댐퍼를 두지 말고이 기사를 읽은 후 생각만큼 화려하지 않을 수도 있습니다. serpentine.com/blog/2008/01/04/why-you-should-not-use-pyinotify
NuclearPeon

1
pyinotify는 매우 파이썬이 아닌 코드 기반에서 메모리 소비에 이르기까지 많은 단점을 가지고 있습니다. 다른 옵션을 찾는 것이 좋습니다.
Tyto

13

Tim Golden의 스크립트를 약간 해킹 한 후 다음과 같은 결과가 나타납니다.

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 )

아마도 더 많은 오류 검사와 관련이있을 수 있지만 로그 파일을보고 화면에 뱉기 전에 약간의 처리를 수행하면 잘 작동합니다.

여러분의 의견에 감사드립니다.


10

폴링과 최소한의 종속성이있는 단일 파일을 보려면 Deestan의 답변을 기반으로 한 완전한 예제가 있습니다 (위).

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
당신은 만들 수 watch_file_cached_stamp루프에 대한 그들을 통해 목록에, 그리고 반복 처리. 그래도 많은 파일로 확장 할 수는 없습니다.
4Oh4

이것이 실행될 때마다 액션을 트리거하지 않습니까? _cached_stamp는 0으로 설정되고 os.stat (self.filename) .st_mtime과 비교됩니다. 생성자에서 _cached_stamp를 os.stat (self.filename) .st_mtime으로 설정해야합니다.
Seanonymous

1
call_func_on_change()의 첫 번째 실행에서 트리거 look()되지만 _cached_stamp업데이트 된 다음 os.stat(self.filename).st_mtime. _cached_stamp변경 값이있을 때까지 다시 트리거되지 않습니다 .
4Oh4

1
첫 실행시 호출 _cached_stamp하지 않으려면 생성자 의 값을 설정할 수 call_func_on_change()있습니다.
4Oh4

스크립트를 사용하여 파일 변경에 대한 함수를 호출했습니다. 내 기능은 당신과 다른 주장을 취하지 않습니다. 나는 그것을 작동시키기 위해 * args, ** kwargs를 제거해야한다고 생각했다. (나는 변경 사항이있는 줄만 넣었다) : self.call_func_on_change(self) def custom_action(): watcher = Watcher(watch_file, custom_action())그러나 이것은 효과가 없었다. 첫 번째 반복 중에 만 조치가 호출되었습니다. 파일이 변경되었습니다. 변경되었습니다. 파일이 변경되었습니다. 파일이 변경되었습니다. 파일이 변경되었습니다 watcher = Watcher(watch_file, custom_action).
zwornik

7

비슷한 질문에 대한 답변 을 확인하십시오 . 파이썬에서 같은 루프를 시도 할 수 있습니다. 이 페이지 는 다음을 제안합니다.

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

또한 파이썬으로 파일 tail () 질문을 참조하십시오 .


sys.stdout.write (line)를 사용할 수 있습니다. 파일이 잘 리면 코드가 작동하지 않습니다. 파이썬에는 내장 함수 파일 ()이 있습니다.
jfs

코드의 수정 된 버전을 게시했습니다. 그것이 효과가 있다면 답에 포함시킬 수 있습니다.
jfs

7

나를위한 가장 간단한 해결책은 워치 독 도구 watchmedo를 사용하는 것입니다.

에서 https://pypi.python.org/pypi/watchdog 지금은 프로세스를하는 SQL 디렉토리에있는 파일 및 실행하는 그들을 필요한 경우 찾습니다.

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

6

글쎄, 파이썬을 사용하고 있기 때문에 파일을 열고 그 줄을 계속 읽을 수 있습니다.

f = open('file.log')

읽은 줄이 비어 있지 않으면 처리합니다.

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

readlineEOF에서 계속 전화 를 해도 괜찮습니다 . 이 경우 빈 문자열을 계속 반환합니다. 그리고 로그 파일에 무언가가 추가되면 필요에 따라 중지 된 위치부터 계속 읽습니다.

이벤트 또는 특정 라이브러리를 사용하는 솔루션을 찾고 있다면 질문에 지정하십시오. 그렇지 않으면이 솔루션이 훌륭하다고 생각합니다.


6

다음은 동일한 트릭을 수행하고 전체 파일을 가져 오지 않는 간단한 Kender 코드 버전입니다.

# 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

이것은 Unix 유형에서 실행되고 dict (file => time)를 사용하여 파일 수정을위한 간단한 감시자를 추가하는 Tim Goldan 스크립트의 또 다른 수정입니다.

사용법 : 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를 지원하도록 업데이트
ronedg

4

Horst Gutmann이 지적한 Tim Golden의 기사 에서 볼 수 있듯이 WIN32는 비교적 복잡하며 단일 파일이 아닌 디렉토리를 감시합니다.

나는 당신이 조사 제안하고 싶습니다 IronPython의 A는, .NET의 파이썬 구현입니다. IronPython을 사용하면 다음을 포함한 모든 .NET 기능을 사용할 수 있습니다

System.IO.FileSystemWatcher

간단한 이벤트 인터페이스로 단일 파일을 처리합니다 .


@Ciasto이므로 기본 Python 설치 대신 Iron Python을 사용할 수 있어야합니다.
존 케이지

1

변경 사항을 파일에서 확인하는 예입니다. 가장 좋은 방법은 아니지만 짧은 방법입니다.

소스가 변경되었을 때 응용 프로그램을 다시 시작하는 데 유용한 도구입니다. 파이 게임을 할 때 이것을 만들었으므로 파일 저장 직후에 효과가 발생하는 것을 볼 수 있습니다.

파이 게임에서 사용될 때 'while'루프에있는 것들이 게임 루프에 업데이트 또는 그 밖의 무엇이든 위치해야합니다. 그렇지 않으면 응용 프로그램이 무한 루프에 빠지고 게임 업데이트가 표시되지 않습니다.

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

웹에서 찾은 재시작 코드를 원한다면 여기있어. (질문과 관련이 없지만 편리 할 수는 있습니다)

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

전자가 원하는 일을하게 만드는 재미를 가지십시오.


OP가 폴링을 통해 원하지 않는다고 표시했지만 .st_mtime대신 대신 사용 하는 .st_size것이 더 안정적이며 짧은 방법입니다.
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

다음은 초당 한 줄 이상을 쓰지 않는 입력 파일을 보는 데 중점을 둔 예제입니다. 목표는 마지막 행 (가장 최근의 쓰기)을 지정된 출력 파일에 추가하는 것입니다. 내 프로젝트 중 하나에서 이것을 복사하고 관련없는 모든 줄을 삭제했습니다. 누락 된 기호를 채우거나 변경해야합니다.

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])

물론, 포괄 QMainWindow 클래스는 꼭 필요한 것은 아닙니다. QFileSystemWatcher 만 사용할 수 있습니다.


0

repyt 라는 간단한 라이브러리를 사용할 수도 있습니다. 다음은 예입니다.

repyt ./app.py

0

아무도 fswatch 를 게시하지 않은 것 같습니다 . 크로스 플랫폼 파일 시스템 감시자입니다. 설치하고 실행 한 후 지시를 따르십시오.

파이썬 및 golang 프로그램과 함께 사용했으며 작동합니다.


0

관련 @ 4Oh4 솔루션은 감시 할 파일 목록을 부드럽게 변경합니다.

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 전용 기능을 모릅니다. 매 초 / 분 / 시간마다 파일의 MD5 해시 (필요한 속도에 따라 다름)를 가져 와서 마지막 해시와 비교할 수 있습니다. 다른 경우 파일이 변경되었음을 알고 최신 줄을 읽습니다.


-6

나는 이런 식으로 시도 할 것입니다.

    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()

루프는 마지막으로 파일을 읽은 이후 새 줄이 있는지 확인합니다.이 줄이 있으면 읽은 다음 functionThatAnalisesTheLine함수에 전달됩니다 . 그렇지 않은 경우 스크립트는 1 초 동안 대기 한 후 프로세스를 재 시도합니다.


4
-1 : 파일 크기가 100MB 일 때 파일을 열고 행을 읽는 것은 좋은 생각이 아닙니다. 당신은 1000의 파일을보고 싶을 때 나쁜 모든 파일마다 실행해야합니다.
존 케이지

1
정말? 파일을 열어 변경 하시겠습니까?
파시
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.