如何从Python中连续读取的文件中删除?

时间:2014-07-31 14:35:06

标签: python file line continuous

我创建了一个python脚本,用于从连续更新的文件('out.txt')中读取并每隔10秒写入一个不同的文件('received.txt')。现在我需要弄清楚如何从'out.txt'文件中删除已读取的数据。这是我到目前为止的代码。

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

在循环之后或循环内部,我是否删除'out.txt'中的数据?我应该使用f.write吗?我在Raspberry Pi上使用Raspbian。 'out.txt'的数据类似于

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

......不断更新。

任何建议都会非常有帮助。谢谢!

1 个答案:

答案 0 :(得分:0)

这种方法存在问题 - 至少在posix上(即除了windows之外几乎所有东西),只要任何进程都有一个打开的文件句柄 - 该文件仍然基本上存在于磁盘上(UNTIL)所有打开的文件手柄已关闭。

因此,如果您有两个进程,一个写入,另一个读取和修剪 - 写入过程必须要知道文件被截断(或删除)并且每次都重新打开目标文件。

这是一种荒谬可笑的做法 - 它需要生产者和消费者之间的沟通,基本上没必要。

聪明的钱只会使用像logrotate这样的内容,因为它已经内置机制来运行一个' HUP'或者重启'命令通知生产者该文件已被截断。

如果您真的只想要循环数据,那么为什么不将sqlite用于包含'包装的模式?当您达到想要消耗的最大行数时?

此示例提供了一个表,当您达到最多20条记录时,该表将删除最旧的记录并插入新记录。根据数据流失量,这可能是您无法承受的奢侈品。但是,如果您只想在系统崩溃之前进行最后1000次CPU负载测量,那么它可以正常工作。事实上,它可以通过使用SQL而不是编写代码的触发器来做一些更优雅的事情,比如生成运行平均值等。

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;