Bagaimana cara menghapus file yang terus dibaca dengan Python?

Saya telah membuat skrip python untuk membaca dari file yang terus diperbarui ('out.txt') dan menulis ke file lain ('received.txt') setiap 10 detik. Sekarang saya perlu mencari cara untuk menghapus data yang sudah dibaca dari file 'out.txt'. Ini kode yang saya miliki sejauh ini.

#!/usr/bin/python

import sys
import time

num_lines = sum(1 for line in open('out.txt')) #find the last line
print num_lines

sys.stdout = open('received.txt', 'w')  #write to the received.txt file
print

f = open('out.txt', 'r') #open ‘out.txt’ with read permissions
f.readline(num_lines)    #read the last line of ’out.txt’
while True:              #start loop to print remaining lines in out.txt
   for line in f:
      print line
   time.sleep(10)        #sleep for 10 seconds

Apakah saya menghapus data di 'out.txt' setelah loop atau di dalam loop? Haruskah saya menggunakan f.write untuk ini? Saya menggunakan Raspbian di Raspberry Pi untuk ini. Seperti apa data untuk 'out.txt'

pemindaian iBeacon...

3F234454-CF6D-4A0F-ADF2-F4911BA9FFA6 1 1 -71 -66

3F234454-CF6D-4A0F-ADF2-F4911BA9FFA6 1 1 -71 -66

3F234454-CF6D-4A0F-ADF2-F4911BA9FFA6 1 1 -71 -66

... terus memperbarui.

Saran apa pun akan sangat membantu. Terima kasih!


person Thomas Hall    schedule 31.07.2014    source sumber
comment
Periksa stackoverflow.com/q/10349781/1860929   -  person Anshul Goyal    schedule 31.07.2014
comment
Menggunakan pipa bernama untuk out.txt adalah sebuah pilihan?   -  person Raul Andres    schedule 31.07.2014
comment
Coba gunakan pipa bernama, menggunakan file teks biasa terdengar sangat aneh.   -  person roippi    schedule 31.07.2014
comment
Kebenaran yang tidak diketahui adalah Anda tidak pernah menghapus beberapa baris dari sebuah file, Anda selalu menulis ulang seluruh file (semua aplikasi melakukannya di balik tirai). Mengapa Anda tidak menggunakan pipa daripada file?   -  person Paulo Scardine    schedule 31.07.2014
comment
Jika Anda membuka file dalam mode tulis/baca (w+), itu akan memotong (menghapus semua konten) file.   -  person okoboko    schedule 31.07.2014
comment
Hati-hati dengan pipa bernama. Jika dibuka dalam mode pemblokiran (default) proses produsen dapat memblokir menunggu konsumen membuka/membaca dari pipa. Hal ini mungkin menjadi masalah bagi produsen jika tidak menduganya.   -  person mhawke    schedule 31.07.2014


Jawaban (1)


Ada masalah dengan pendekatan ini - setidaknya di posix (yaitu hampir semuanya kecuali windows), selama proses apa pun memiliki pegangan file terbuka - file tersebut pada dasarnya masih ada di disk (SAMPAI) semua pegangan file yang terbuka ditutup.

Jadi jika Anda memiliki dua proses, satu penulisan, dan proses lainnya membaca dan memotong - proses penulisan harus menyadari bahwa file tersebut terpotong (atau dihapus) dan membuka kembali file tujuan setiap saat.

Ini adalah cara yang sangat buruk untuk melakukan hal tersebut - memerlukan komunikasi antara produsen dan konsumen dan pada dasarnya tidak diperlukan.

Uang pintar hanya akan menggunakan sesuatu seperti logrotate yang memiliki mekanisme bawaan untuk menjalankan perintah 'HUP' atau 'restart' untuk memberi tahu produsen bahwa file telah terpotong.

Jika Anda benar-benar hanya menginginkan data round-robin, mengapa tidak menggunakan sqlite dengan skema yang 'membungkus' saat Anda mencapai jumlah baris maksimum yang ingin Anda gunakan?

Contoh ini menyediakan tabel yang akan menghapus catatan terlama dan menyisipkan yang baru ketika Anda mencapai maksimum 20 catatan. Tergantung pada jumlah churn data, hal ini mungkin merupakan sebuah kemewahan yang tidak mampu Anda beli. Tetapi jika Anda hanya ingin 1000 pengukuran terakhir beban CPU sebelum sistem crash.. itu akan berfungsi dengan baik. Faktanya, ia bisa melakukan beberapa hal yang lebih elegan seperti menghasilkan rata-rata berjalan, dll melalui pemicu menggunakan SQL daripada menulis kode..

CREATE TABLE activity_t (
  id        INTEGER PRIMARY KEY AUTOINCREMENT,
  seq       INTEGER UNIQUE,
  ts        TEXT DEFAULT CURRENT_TIMESTAMP,
  bin       TEXT NOT NULL,
  path      TEXT NOT NULL);

-- sqlite_sequence table:
INSERT INTO activity_t ( seq, bin, path ) VALUES ( -1, 'init', 'init' );
DELETE FROM activity_t WHERE seq = -1;

-- view
CREATE VIEW activity AS SELECT id, seq, ts, bin, path FROM activity_t;

-- trigger to snipe inserts and handle the 'wrap around' limitation
CREATE TRIGGER activity_trg
  INSTEAD OF INSERT ON activity
  FOR EACH ROW
  BEGIN
    INSERT OR REPLACE INTO activity_t ( seq, bin, path ) VALUES (
      ( SELECT seq + 1 FROM sqlite_sequence WHERE name = 'activity_t' ) %
    20,
    NEW.bin,
    NEW.path);
  END;
person synthesizerpatel    schedule 31.07.2014