Saya memiliki file log yang sedang ditulis oleh proses lain yang ingin saya perhatikan perubahannya. Setiap kali perubahan terjadi, saya ingin membaca data baru untuk melakukan pemrosesan.
Apa cara terbaik untuk melakukan ini? Saya berharap akan ada semacam pengait dari perpustakaan PyWin32. Saya telah menemukan win32file.FindNextChangeNotification
fungsinya tetapi tidak tahu bagaimana cara memintanya menonton file tertentu.
Jika ada yang melakukan hal seperti ini saya akan sangat bersyukur mendengar bagaimana ...
[Sunting] Saya seharusnya menyebutkan bahwa saya mencari solusi yang tidak memerlukan polling.
[Sunting] Kutukan! Tampaknya ini tidak berfungsi pada drive jaringan yang dipetakan. Saya kira windows tidak 'mendengar' pembaruan ke file seperti di disk lokal.
strace
pemantauanwrite
untuk iniJawaban:
Sudahkah Anda melihat dokumentasi yang tersedia di http://timgolden.me.uk/python/win32_how_do_i/watch_directory_for_changes.html ? Jika Anda hanya membutuhkannya untuk bekerja di bawah Windows, contoh ke-2 tampaknya persis seperti yang Anda inginkan (jika Anda bertukar jalur direktori dengan salah satu file yang ingin Anda tonton).
Kalau tidak, polling mungkin akan menjadi satu-satunya pilihan platform-independen.
Catatan: Saya belum mencoba solusi ini.
sumber
Apakah Anda mencoba menggunakan Watchdog ?
sumber
easy_install
? Memeriksa. Lisensi gratis? Periksa . Memecahkan masalah pada platform besar? Periksa . Saya mendukung jawaban ini. Hanya catatan: contoh pada halaman proyek mereka tidak bekerja di luar kotak. Gunakan yang di github mereka sebagai gantinya.Jika polling cukup baik untuk Anda, saya hanya akan menonton jika stat file "waktu yang diubah" berubah. Untuk membacanya:
(Perhatikan juga bahwa solusi peristiwa perubahan asli Windows tidak berfungsi dalam semua keadaan, misalnya pada drive jaringan.)
sumber
if self._cached_stamp is not None
.Jika Anda menginginkan solusi multi platform, maka periksa QFileSystemWatcher . Berikut contoh kode (tidak disanitasi):
sumber
watchdog
paket adalah jawaban yang tepatPySide
untuk itu alih-alihPyQt
untuk penggunaan sekecil itu.Seharusnya tidak bekerja di windows (mungkin dengan cygwin?), Tetapi untuk pengguna unix, Anda harus menggunakan panggilan sistem "fcntl". Berikut ini adalah contoh dalam Python. Sebagian besar kode yang sama jika Anda perlu menuliskannya dalam C (nama fungsi yang sama)
sumber
Lihat pyinotify .
inotify menggantikan dnotify (dari jawaban sebelumnya) di linux yang lebih baru dan memungkinkan tingkat file daripada pemantauan tingkat direktori.
sumber
Nah setelah sedikit peretasan skrip Tim Golden, saya memiliki yang berikut ini yang tampaknya bekerja dengan baik:
Ini mungkin bisa dilakukan dengan memuat lebih banyak pengecekan kesalahan, tetapi untuk hanya menonton file log dan melakukan beberapa pemrosesan sebelum meludahkannya ke layar, ini bekerja dengan baik.
Terima kasih semuanya atas masukan Anda - hal-hal hebat!
sumber
Untuk menonton satu file dengan polling, dan dependensi minimal, berikut adalah contoh yang sepenuhnya diperlengkapi, berdasarkan jawaban dari Deestan (di atas):
sumber
watch_file
dan_cached_stamp
masuk ke dalam daftar, dan beralih di dalamnya dalam for loop. Tidak benar-benar skala baik untuk sejumlah besar filecall_func_on_change()
akan dipicu pada jalankan pertamalook()
, tetapi kemudian_cached_stamp
diperbarui, jadi tidak akan terpicu lagi hingga nilaios.stat(self.filename).st_mtime. _cached_stamp
perubahan._cached_stamp
dalam konstruktor jika Anda tidak ingincall_func_on_change()
dipanggil pada jalankan pertamaself.call_func_on_change(self) def custom_action(): watcher = Watcher(watch_file, custom_action())
Tapi ini tidak berhasil. Tindakan hanya dipanggil selama iterasi pertama: File berubah ya, diubah File berubah File berubah File berubah Itu mulai bekerja ketika saya menyimpan * argumen dan menyebutnya:watcher = Watcher(watch_file, custom_action)
Saya kesulitan bertanya-tanya mengapa?Periksa jawaban saya untuk pertanyaan serupa . Anda bisa mencoba loop yang sama dengan Python. Halaman ini menyarankan:
Lihat juga tail pertanyaan () file dengan Python .
sumber
Solusi paling sederhana bagi saya adalah menggunakan alat pengawas watchmedo
Dari https://pypi.python.org/pypi/watchdog sekarang saya memiliki proses yang mencari file sql dalam direktori dan mengeksekusi mereka jika perlu.
sumber
Nah, karena Anda menggunakan Python, Anda bisa membuka file dan terus membaca baris darinya.
Jika baris yang dibaca tidak kosong , Anda memprosesnya.
Anda mungkin kehilangan bahwa tidak masalah untuk terus menelepon
readline
di EOF. Ini hanya akan terus mengembalikan string kosong dalam kasus ini. Dan ketika sesuatu ditambahkan ke file log, bacaan akan dilanjutkan dari tempat itu berhenti, seperti yang Anda butuhkan.Jika Anda mencari solusi yang menggunakan acara, atau perpustakaan tertentu, harap tentukan ini di pertanyaan Anda. Kalau tidak, saya pikir solusi ini baik-baik saja.
sumber
Ini adalah versi sederhana dari kode Kender yang tampaknya melakukan trik yang sama dan tidak mengimpor seluruh file:
sumber
Ini adalah modifikasi lain dari skrip Tim Goldan yang berjalan pada tipe unix dan menambahkan pengamat sederhana untuk modifikasi file dengan menggunakan dict (file => waktu).
penggunaan: whateverName.py path_to_dir_to_watch
sumber
Seperti yang dapat Anda lihat di artikel Tim Golden , ditunjukkan oleh Horst Gutmann , WIN32 relatif kompleks dan mengawasi direktori, bukan satu file.
Saya ingin menyarankan Anda melihat ke IronPython , yang merupakan implementasi .NET python. Dengan IronPython Anda dapat menggunakan semua fungsionalitas .NET - termasuk
Yang menangani file tunggal dengan antarmuka Acara sederhana .
sumber
Ini adalah contoh memeriksa file untuk perubahan. Cara yang mungkin bukan cara terbaik untuk melakukannya, tetapi tentu saja ini cara yang singkat.
Alat praktis untuk memulai ulang aplikasi ketika ada perubahan pada sumbernya. Saya membuat ini ketika bermain dengan pygame sehingga saya dapat melihat efeknya terjadi segera setelah file disimpan.
Saat digunakan dalam pygame pastikan barang-barang di loop 'while' ditempatkan di loop game Anda alias perbarui atau apa pun. Kalau tidak, aplikasi Anda akan macet dalam loop tak terbatas dan Anda tidak akan melihat pembaruan game Anda.
Jika Anda menginginkan kode restart yang saya temukan di web. Ini dia. (Tidak relevan dengan pertanyaan, meskipun bisa berguna)
Bersenang-senang membuat elektron melakukan apa yang Anda inginkan.
sumber
.st_mtime
daripada.st_size
akan lebih dapat diandalkan dan cara yang sama singkatnya untuk melakukan ini, meskipun OP telah mengindikasikan bahwa ia tidak ingin melakukannya melalui polling.sumber
Berikut adalah contoh diarahkan menonton file input yang menulis tidak lebih dari satu baris per detik tetapi biasanya jauh lebih sedikit. Tujuannya adalah untuk menambahkan baris terakhir (paling baru tulis) ke file output yang ditentukan. Saya telah menyalin ini dari salah satu proyek saya dan baru saja menghapus semua baris yang tidak relevan. Anda harus mengisi atau mengubah simbol yang hilang.
Tentu saja, kelas QMainWindow yang melingkupi tidak sepenuhnya diperlukan, yaitu. Anda bisa menggunakan QFileSystemWatcher sendirian.
sumber
Anda juga dapat menggunakan pustaka sederhana bernama repyt , berikut ini sebuah contoh:
sumber
Tampaknya tidak ada yang memposting fswatch . Ini adalah pengamat sistem file lintas platform. Instal saja, jalankan dan ikuti petunjuknya.
Saya sudah menggunakannya dengan program python dan golang dan hanya berfungsi.
sumber
solusi terkait @ 4Oh4 perubahan halus untuk daftar file untuk ditonton;
sumber
Solusi terbaik dan paling sederhana adalah dengan menggunakan pygtail: https://pypi.python.org/pypi/pygtail
sumber
Saya tidak tahu fungsi khusus Windows. Anda bisa mencoba mendapatkan hash MD5 file setiap detik / menit / jam (tergantung seberapa cepat Anda membutuhkannya) dan membandingkannya dengan hash terakhir. Ketika berbeda, Anda tahu file telah diubah dan Anda membacakan baris terbaru.
sumber
Saya akan mencoba sesuatu seperti ini.
Loop memeriksa apakah ada baris baru sejak file terakhir kali dibaca - jika ada, itu dibaca dan diteruskan ke
functionThatAnalisesTheLine
fungsi. Jika tidak, skrip menunggu 1 detik dan coba lagi prosesnya.sumber