পরিবর্তনের জন্য আমি কীভাবে একটি ফাইল দেখব?


323

আমার কাছে একটি লগ ফাইল রয়েছে যা অন্য একটি প্রক্রিয়া দ্বারা লিখিত হচ্ছে যা আমি পরিবর্তনগুলির জন্য দেখতে চাই। প্রতিবার যখন কোনও পরিবর্তন ঘটে আমি নতুন তথ্য এটিতে কিছু প্রক্রিয়াজাতকরণ করতে চাই।

এটি করার সর্বোত্তম উপায় কী? আমি আশা করছিলাম পাইবুইন 32 লাইব্রেরি থেকে কোনও রকম হুক হবে। আমি win32file.FindNextChangeNotificationফাংশনটি খুঁজে পেয়েছি তবে নির্দিষ্ট ফাইলটি দেখার জন্য এটি কীভাবে জিজ্ঞাসা করতে হবে তার কোনও ধারণা নেই।

যদি কেউ এরকম কিছু করে থাকে তবে আমি কীভাবে তা শুনে সত্যিই কৃতজ্ঞ হব ...

[সম্পাদনা] আমার উল্লেখ করা উচিত ছিল যে আমি এমন একটি সমাধানের পরেছিলাম যার পক্ষে ভোটদানের প্রয়োজন হয় না।

[সম্পাদনা] অভিশাপ! মনে হচ্ছে এটি কোনও ম্যাপযুক্ত নেটওয়ার্ক ড্রাইভে কাজ করে না। আমি অনুমান করছি যে উইন্ডোগুলি কোনওভাবে স্থানীয় ডিস্কে ফাইলের কোনও আপডেট 'শোনে না'।


1
লিনাক্স-এ একজন stracewrite
এটির

@ সিমাওর উত্তরটি পাইথন-ওয়াচডগ ব্যবহার করে। পাইথন-ওয়াচডগের দুর্দান্ত ডকুমেন্টেশন রয়েছে -> এখানে ["কুইকস্টার্ট"] ডকুমেন্টেশনের লিঙ্ক রয়েছে যা একটি ন্যূনতম কোড উদাহরণ প্রদান করে যা বর্তমান কার্যকরী ডিরেক্টরিটি দেখে।
ট্রেভর বয়েড স্মিথ

উত্তর:


79

আপনি কি ইতিমধ্যে http://timgolden.me.uk/python/win32_h__d_i/watch_directory_for_changes.html এ উপলব্ধ নথিটি দেখেছেন ? যদি আপনার কেবল উইন্ডোজের অধীনে কাজ করার প্রয়োজন হয় তবে দ্বিতীয় উদাহরণটি যা চান তা হ'ল বলে মনে হচ্ছে (আপনি যদি দেখতে চান এমন ফাইলের সাথে ডিরেক্টরিটির পথ বিনিময় করেন)।

অন্যথায়, পোলিং সম্ভবত একমাত্র সত্যই প্ল্যাটফর্ম-স্বতন্ত্র বিকল্প হবে।

দ্রষ্টব্য: আমি এর কোনও সমাধানের চেষ্টা করিনি।


5
এই উত্তরটি উইন্ডোজ-নির্দিষ্ট, তবে দেখা যাচ্ছে যে এই সমস্যার কয়েকটি ক্রস-প্ল্যাটফর্ম সমাধানও এখানে পোস্ট করা হয়েছে।
অ্যান্ডারসন সবুজ

কোনও মানদণ্ড আছে, যদি এই প্রক্রিয়াটি ধীর হয় তবে সি ++ এর মতো স্থানীয় ভাষায় এটি প্রয়োগ করা হয়?
ব্যবহারকারী 1767754

উদ্ধৃত উত্স থেকে প্রাসঙ্গিক বিষয়বস্তু inোকানো আরও ভাল কারণ তারা পুরানো হতে পারে।
ট্রিইরিওন

2
(১.) এই উত্তরের শেষে একটি শক্তিশালী অস্বীকৃতি ... "আমি এর কোনও সমাধানের চেষ্টা করিনি"। (২.) এই উত্তরটি কম-বেশি একটি "লিঙ্ক কেবল" উত্তর (৩.) উত্তরে "পোলিং" উল্লেখ করা হয়েছে তবে এর পরে সহায়ক কিছু সরবরাহ করে না ... যেখানে @ ডিস্টানের উত্তর হিসাবে পোলিংয়ে কিছু ভাল তথ্য সরবরাহ করা হয়েছে
ট্রেভর বয়ড স্মিথ

283

আপনি কি ওয়াচডোগ ব্যবহার করার চেষ্টা করেছেন ?

পাইথন এপিআই লাইব্রেরি এবং ফাইল সিস্টেম ইভেন্টগুলি নিরীক্ষণের জন্য শেল ইউটিলিটিগুলি।

ডিরেক্টরি মনিটরিং দিয়ে সহজ করা

  • একটি ক্রস প্ল্যাটফর্ম API।
  • ডিরেক্টরি পরিবর্তনের প্রতিক্রিয়া হিসাবে কমান্ড চালানোর জন্য একটি শেল সরঞ্জাম।

কুইকস্টার্টে একটি সাধারণ উদাহরণ দিয়ে দ্রুত শুরু করুন ...


56
এর সাথে ইনস্টলযোগ্য easy_install? পরীক্ষা করে দেখুন। বিনামূল্যে অনুমতিপত্র? চেক । বড় প্ল্যাটফর্মে সমস্যার সমাধান? চেক । আমি এই উত্তরটি সমর্থন করি। কেবলমাত্র নোট করুন: তাদের প্রকল্প পৃষ্ঠার উদাহরণ বাক্স থেকে কার্যকর হয় না। ব্যবহার করুন তাদের GitHub এক পরিবর্তে।
ইনাইমথি

6
আমরা নজরদারি ব্যবহার করি। আমরা কিউফাইলসিস্টেমওয়াটারে স্যুইচ করতে পারি। কেবল একটি যথাযথ সতর্কতা- ওয়াচডগটি ভাল তবে সমস্ত প্ল্যাটফর্মগুলিতে নিখুঁত থেকে দূরে (এই সময়ে)। প্রতিটি ওএস এর আইডিয়োসিএনসিজেস থাকে। সুতরাং, আপনি এটিকে নিখুঁত করতে উত্সর্গীকৃত না হলে আপনি আপনার চুলগুলি বাইরে টানবেন। আপনি যদি কেবল 10 টি ফাইল বা তাই দেখার জন্য সন্ধান করছেন তবে আমি জরিপ করব। ওএস ডিস্ক ক্যাশে করা খুব পরিপক্ক এবং ওয়াচডগ কোনওভাবেই পোলিং এপিআই জড়িত। এটি মূলত বিশাল ফোল্ডার কাঠামো IMHO দেখার জন্য।
সাইলেন্টস্টিল

3
ওয়াচডগ সহ আমার একটি গ্রিপ এটির অনেকগুলি নির্ভরতা many পাইকিউটের চেয়ে কম অবশ্যই, তবে এটি কাজ করে না এবং সর্বনিম্ন, সেরা অনুশীলন, এক-কাজ-এবং-এটি-সঠিক সমাধানের মতো মনে হয় না।
AndreasT

1
@ এডেনফ্রুমুফা কি এখানে সঠিক? ওয়াচডগ কি আসলেই ফাইলগুলিকে লক করে রাখে, তাই তাদের পর্যবেক্ষণ করার জন্য পর্যায়ক্রমে এগুলি সম্পাদনা করা যায় না? আমি দৃly়ভাবে বিশ্বাস করতে পারি যে, এটি সম্পূর্ণ অকেজো হবে।
মিশেল মুলার

1
@ মিশেলমেলার আমি কেবল এই উদাহরণটি পরীক্ষা করেছি (নীচের লিঙ্কটি দেখুন) এবং এটি কার্যকর! আগে কী ভুল ছিল তা নিশ্চিত নন, তবে এই উত্তরটি কোনও উদাহরণ দেয় না। stackoverflow.com/a/18599427/2230844
denfromufa

92

যদি পোলিং আপনার পক্ষে যথেষ্ট ভাল হয় তবে আমি কেবল "সংশোধিত সময়" ফাইলের স্থিতি পরিবর্তন করে তা দেখতে চাই। এটি পড়তে:

os.stat(filename).st_mtime

(এছাড়াও লক্ষ করুন যে উইন্ডোজ নেটিভ পরিবর্তন ইভেন্ট সমাধানটি সমস্ত পরিস্থিতিতে যেমন কাজ করে না, যেমন নেটওয়ার্ক ড্রাইভগুলিতে কাজ করে না))

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
আপনি কীভাবে একটি বিরতিতে এটি করতে পারেন?
দোপাট্রমান

1
@ দোপাট্রামন এখানে আপনি কীভাবে একটি বিরতিতে এটি করতে পারবেন `আমদানির সময় sys আমদানি সময় পাব = বানর () সত্য হিসাবে: চেষ্টা করুন: সময়.স্লাইপ (1) পাব.ওয়াচ () কীবোর্ড ইন্টারটার্ন্ট ব্যতীত: মুদ্রণ ('one n সম্পন্ন') বিরতি ব্যতীত : মুদ্রণ (এফ আনুষাঙ্গিক ত্রুটি: ys sys.exc_info () [0]) ') `
ভ্লাদ বেজডেন

দুর্দান্ত সহজ সমাধান! আমি এটা প্রথমবার চালনার পরিবর্তিত ফাইল প্রতিবেদনে রাখার একটি চেক যোগ করেছেন: if self._cached_stamp is not None
নওম্যানন

50

আপনি যদি একটি মাল্টিপ্লাটফর্ম সমাধান চান, তবে কিউফাইলসিসটামওয়াটারটি পরীক্ষা করুন । এখানে একটি উদাহরণ কোড (স্যানিটাইজড নয়):

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
আমি মনে করি যে এই গোছের সম্ভবত সম্ভবত সেরা উত্তর দেওয়া হয়েছে যে তারা হয় ক) উইন 32 এর ফাইলসিস্টেমওয়্যাচার অবজেক্টের উপর নির্ভর করে এবং পোর্ট করা যায় না খ) ফাইলের জন্য পোল (যা পারফরম্যান্সের জন্য খারাপ এবং স্কেল হবে না)। এটি অত্যন্ত দুঃখের বিষয় পাইথনটিতে এই সুবিধাটি তৈরি করা নেই কারণ পাইকিউটি একটি বিশাল নির্ভরতা যদি আপনি ব্যবহার করছেন সমস্ত কিউফাইসিসটেমওয়াটার ক্লাস।
ক্যাডেন্ট অরেঞ্জ

4
আমি এই সমাধানটি পছন্দ করি। আমি এটি উল্লেখ করতে চেয়েছিলাম যে এটির কাজ করার জন্য আপনার একটি QApplication উদাহরণের প্রয়োজন হবে, আমি "অ্যাপ্লিকেশন = QtGui.Q অ্যাপ্লিকেশন (sys.argv)" ইম্পোর্টের ঠিক নীচে এবং তারপরে সংকেত সংযোগের পরে "app.exec_ ()" যুক্ত করেছি।
স্পেন্সওয়াহ

এটি কেবল একটি লিনাক্স বাক্সে পরীক্ষা করে দেখছি যে ডিরেক্টরি_চেনাচীন পদ্ধতিটি ডাকা হচ্ছে, কিন্তু ফাইল_চেনাড নয়।
কেন কিন্ডার

@ ক্যাডেন্টআরেঞ্জ, আপনি যদি পাইকিউটি নির্ভরতা পছন্দ না করেন তবে watchdogপ্যাকেজটি সঠিক উত্তর
মাইক পেনিংটন ২

কেন এইরকম ছোট ব্যবহারের PySideপরিবর্তে এর PyQtজন্য ব্যবহার করবেন না।
সিয়াস্তো পাইকার্জ

29

এটি উইন্ডোতে কাজ করা উচিত নয় (সম্ভবত সাইগউইনের সাথে?), তবে ইউনিক্স ব্যবহারকারীর জন্য আপনার "fcntl" সিস্টেম কলটি ব্যবহার করা উচিত। পাইথনের উদাহরণ এখানে। আপনি যদি এটি সিতে লিখতে চান তবে এটি বেশিরভাগ একই কোড (একই ফাংশনের নাম)

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
লিনাক্স কার্নেল ২.6.৩১ এর সাথে একটি এক্সট ৪ ফাইল সিস্টেমে (উবুন্টু ১০.০৪-তে) আকর্ষণীয় কাজ করে, যদিও এটি কেবল ডিরেক্টরিগুলির জন্য - এটি কোনও আইওআরর "ডিরেক্টরি নয়" উত্থাপন করে যদি আমি কোনও ফাইলের সাথে এটি ব্যবহার করি।
ডেভিড আন্ডারহিল

1
গ্রেট! আমার জন্য একই, কেবল ডিরেক্টরিতে কাজ করে এবং এই ডিরেক্টরিতে ফাইলগুলি দেখে। তবে এটি উপ-ডিরেক্টরিগুলিতে পরিবর্তিত ফাইলগুলির জন্য কাজ করবে না, তাই দেখে মনে হচ্ছে আপনাকে সাবডাইরেক্টরিগুলি দিয়ে চলতে হবে এবং সেগুলি সমস্ত দেখতে হবে। (বা এটি করার আরও ভাল উপায় আছে?)
lfagundes

20

চেক আউট pyinotify

ইনোটিফাই নতুন লিনাক্সে ডন্টাইফাই (পূর্বের উত্তর থেকে) প্রতিস্থাপন করে এবং ডিরেক্টরি-স্তর পর্যবেক্ষণের পরিবর্তে ফাইল-স্তরকে অনুমতি দেয়।


5
এই উত্তরটি নিয়ে কোনও ছাপ ছাপানোর জন্য নয়, তবে এই নিবন্ধটি পড়ার পরে আমি বলব যে এটি চিন্তার মতো চটকদার সমাধান নাও হতে পারে। serpentine.com/blog/2008/01/04/why-you-should-not-use-pyinotify
নিউক্লিয়ারপিয়ন

1
পাইনোটাইফাইয়ের খুব অকার্যকর কোড বেস থেকে শুরু করে মেমরির ব্যবহার পর্যন্ত অনেক অসুবিধা রয়েছে। অন্যান্য বিকল্পগুলির জন্য সন্ধান করা আরও ভাল ..
টায়্টো

13

টিম গোল্ডেনের স্ক্রিপ্টটি বেশ কিছুটা হ্যাক করার পরে, আমার নিম্নলিখিতগুলি রয়েছে যা বেশ ভালভাবে কাজ করছে বলে মনে হচ্ছে:

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

ভোটদান, এবং ন্যূনতম নির্ভরতা সহ একটি একক ফাইল দেখার জন্য, এখানে ডিস্টান (উপরে) এর উত্তরের উপর ভিত্তি করে একটি সম্পূর্ণ মাংসলগ্ন উদাহরণ রয়েছে :

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এগুলিতে পরিণত করতে পারেন এবং লুপের জন্য সেগুলি জুড়ে পুনরাবৃত্তি করতে পারেন । যদিও প্রচুর সংখ্যক ফাইলে সত্যই স্কেল হয় না
15:56-

এটি প্রতিবার সঞ্চালনের সাথে সাথে কি ক্রিয়াটি ট্রিগার করে না? _ ক্যাচড_স্ট্যাম্প 0 এ সেট করা হয় এবং তারপরে os.stat (স্ব.ফিল নাম) .st_mটাইমের সাথে তুলনা করা হয়। _ ক্যাচড_স্ট্যাম্পটি os.stat (self.filename) এ সেট করা উচিত st কনস্ট্রাক্টরেস্ট_মটাইম, না?
বেনামে

1
call_func_on_change()প্রথম রান করার সময় ট্রিগার করা হবে look(), তবে _cached_stampআপডেট করা হবে, সুতরাং os.stat(self.filename).st_mtime. _cached_stampপরিবর্তনের মান না হওয়া পর্যন্ত আবার ট্রিগার করা হবে না ।
ওহ

1
আপনি _cached_stampযদি call_func_on_change()প্রথম দৌড়ে ডাকতে না চান তবে আপনি কনস্ট্রাক্টরের মান নির্ধারণ করতে পারেন
ওহ

আমি ফাইল স্ক্রিপ্টে কিছু ফাংশন কল করতে আপনার স্ক্রিপ্টটি ব্যবহার করেছি। আমার ফাংশনটি আপনার মতবিরোধের সাথে কোনও যুক্তি নেবে না। আমি ভেবেছিলাম এটি কার্যকর করার জন্য আমাকে * আরগস, ** কাওয়ারগুলি অপসারণ করা দরকার যা দেখেছি (আমি পরিবর্তনগুলির সাথে কেবল লাইন রেখেছি): 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

পাইথন সহ একটি ফাইল প্রশ্ন টেল () দেখুন


আপনি sys.stdout.write (লাইন) করতে পারেন। ফাইলটি কেটে ফেলা হলে আপনার কোড কাজ করবে না। পাইথনে ফাংশন ফাইল () অন্তর্নির্মিত রয়েছে।
jfs

আমি আপনার কোডের একটি পরিবর্তিত সংস্করণ পোস্ট করেছি। যদি এটি আপনার পক্ষে কাজ করে তবে আপনি এটি আপনার উত্তরে অন্তর্ভুক্ত করতে পারেন।
jfs

7

আমার জন্য সহজ সমাধানটি ওয়াচডগের সরঞ্জাম ওয়াচমেডো ব্যবহার করছে

Https://pypi.python.org/pypi/watchdog থেকে আমার এখন একটি প্রক্রিয়া রয়েছে যা একটি ডিরেক্টরিতে থাকা এসকিএল ফাইলগুলি অনুসন্ধান করে এবং প্রয়োজনে এগুলি সম্পাদন করে।

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

আপনি মিস করতে পারেন যে কল করা ঠিক আছে readline ইওএফ-তে করে । এটি কেবল এই ক্ষেত্রে একটি খালি স্ট্রিং ফিরিয়ে রাখবে। এবং যখন কোনও কিছু লগ ফাইলে সংযুক্ত করা হয়, আপনার প্রয়োজন অনুযায়ী পড়াটি যেখানেই থামেছে সেখান থেকে চালিয়ে যাওয়া হবে।

আপনি যদি এমন কোনও সমাধান খুঁজছেন যা ইভেন্টগুলি বা কোনও নির্দিষ্ট গ্রন্থাগার ব্যবহার করে, দয়া করে আপনার প্রশ্নে এটি নির্দিষ্ট করুন। অন্যথায়, আমি মনে করি এই সমাধানটি ঠিক আছে।


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

এটি টিম গোল্ডেনের স্ক্রিপ্টের আরেকটি পরিবর্তন যা ইউনিক্স ধরণের উপরে চলে এবং ডিক (ফাইল => সময়) ব্যবহার করে ফাইল পরিবর্তনের জন্য একটি সাধারণ প্রহরী যুক্ত করে।

ব্যবহার: যাইহোক নাম.পি.পি.পথ_ টু_ডির_ টু_ওয়াচ

#!/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


4

আপনি হোস্ট গুটম্যান দ্বারা নির্দেশিত টিম গোল্ডেনের নিবন্ধে যেমন দেখতে পাচ্ছেন , ডাব্লুআইএন 32 তুলনামূলকভাবে জটিল এবং ডিরেক্টরিগুলি দেখায়, একটি ফাইল নয়।

আমি আপনাকে আয়রন পাইথনটি সন্ধান করার পরামর্শ দিতে চাই , এটি একটি নেট নেট পাইথন বাস্তবায়ন। আয়রনপাইথনের সাহায্যে আপনি সমস্ত .NET কার্যকারিতা - সহ ব্যবহার করতে পারেন

System.IO.FileSystemWatcher

যা সাধারণ ইভেন্ট ইন্টারফেসের সাহায্যে একক ফাইলগুলি পরিচালনা করে ।


@ কিয়াস্তো কারণ তখন আপনার কাছে বেসিক পাইথন ইনস্টলেশন না করে আয়রন পাইথন পাওয়া উচিত।
জন কেজ

1

পরিবর্তনের জন্য ফাইল চেক করার এটি উদাহরণ। এটি করার সর্বোত্তম উপায় নাও হতে পারে তবে এটি অবশ্যই একটি সংক্ষিপ্ত পথ।

উত্সটিতে পরিবর্তনগুলি করা হয়ে গেলে অ্যাপ্লিকেশনটি পুনরায় চালু করার কার্যকর সরঞ্জাম। পাইগামের সাথে খেলে আমি এটি তৈরি করেছি যাতে ফাইল সংরক্ষণের সাথে সাথেই প্রভাবগুলি ঘটে যায় তা দেখতে পাচ্ছি।

যখন পাইগামে ব্যবহৃত হয় তা নিশ্চিত হয়ে নিন যে আপনার খেলার গতির লুপে ওরফে আপডেট বা যে কোনও কিছুতে 'যখন' লুপটি রাখা হয়েছে। অন্যথায় আপনার অ্যাপ্লিকেশন একটি অসীম লুপে আটকে যাবে এবং আপনি আপনার গেম আপডেট হওয়া দেখতে পাবেন না।

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)

ইলেক্ট্রনগুলি যা করতে চায় তা করতে মজা করুন।


এর .st_mtimeপরিবর্তে ব্যবহার .st_sizeকরা আরও নির্ভরযোগ্য এবং এটি করার সমানভাবে স্বল্প উপায় বলে মনে হয়, যদিও ওপি ইঙ্গিত দিয়েছে যে তিনি ভোটের মাধ্যমে এটি করতে চান না।
মার্টিনো

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 শ্রেণীর কঠোরভাবে প্রয়োজন হয় না, অর্থাত্‍। আপনি একা কিউফাইলসিস্টেমওয়াটার ব্যবহার করতে পারেন।



0

দেখে মনে হচ্ছে যে কেউ fswatch পোস্ট করেনি । এটি একটি ক্রস প্ল্যাটফর্ম ফাইল সিস্টেম প্রহরী। কেবল এটি ইনস্টল করুন, এটি চালান এবং অনুরোধগুলি অনুসরণ করুন।

আমি অজগর এবং গোলং প্রোগ্রামগুলির সাথে এটি ব্যবহার করেছি এবং এটি কেবল কার্যকর।


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

আমি কোনও উইন্ডোজ নির্দিষ্ট ফাংশন জানি না। আপনি প্রতি সেকেন্ড / মিনিট / ঘন্টা ধরে ফাইলের 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: ফাইলগুলি খুলতে এবং লাইনগুলি পঠন করা কোনও দুর্দান্ত ধারণা নয় যখন ফাইলগুলি 100 এমবি বড় হতে পারে। আপনাকে এটি প্রতিটি ফাইলের জন্য চালাতে হবে যা আপনি যখন 1000 এর ফাইল দেখতে চান তখন খারাপ হবে।
জন কেজ

1
সত্যি? পরিবর্তনের জন্য ফাইল খুলছেন?
ফারশিদ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.