2012-06-18 109 views
3

我试图打开一个文件并从最后一个读取点读取。我的文件相当大(20 Mb到〜1 Gb)经过一番研究后,似乎tell()和seek()将是执行此操作最有效的方法之一。我试过以下代码如何让tell()工作

opened = open(filename, "rU") 
f1 = csv.reader(opened) 
k = [] 
for line in f1: 
    k.append(opened.tell()) 

当我这样做时,列表中的每个值都是8272 Long。这是否意味着我不能使用此实现?有什么我失踪?谢谢你的帮助!

我在Windows 7中运行的Python 2.7

更新

拼凑后,这里的一切教训和试错我碰到下面的代码

opened = open(filename, "rU") 
k = [0] 
where = 1 
for switch in opened: 
    where += len(switch) + 1 
    f = StringIO.StringIO(switch) 
    interesting = csv.reader(f, delimiter=',') 
    good_values = interesting.next() 
    k.append(where) 

return k 

这允许用户确切地知道文件中要去的地方,同时仍然能够根据其格式来解析它。我不完全确定为什么需要不断补充偏移量(看来,换行符在len()中没有被准确计算)。

回答

1

看起来csv.reader正在以8272字节的块读取文件,这就是为什么你多次从opened.tell()看到这个数字 - 直到我猜你已经读取了文件中所有在0范围内的行-8272。之后你会看到8272 * 2几次,确切的数字将取决于缓冲区读取行的长度。

因此,基本上,在您的程序中,tell()不会为您提供新的CSV行的偏移量,正如您似乎认为的那样。它只告诉你当前读取的文件区域末尾的偏移量,该偏移量是由用于实现Python IO功能的系统函数使用的内部OS缓冲区。

+0

所以我迭代了“打开”并添加了字符串的长度。这给了正确的价值。我仍然想使用csv阅读器,因为这是我正在阅读的文件的格式。我正在使用理解来实现它。 比使用正则表达式更有效吗?有没有更有效的方法来解决这个问题? T –

+0

不确定你所做的'理解'。如果你有一种方法可以正确地计算给定行的偏移量,为什么不重新启动open.seek来重新启动上次处理过的csv行之后的文件偏移量,然后将打开的值传递给csv.reader构造函数?这应该工作。我不推荐用于处理大型csv文件的正则表达式。 – piokuc

+0

问题是任何使用csv阅读器会使事情复杂化。我试图根据csv格式解析文件,但为了获得准确的位置数量,我必须将所有字符加起来。我会定期阅读文件以寻找任何新的更改,这就是为什么我想要查找文件脱落的原因。做一个运行计数或将每行作为原始输入,然后按照csv格式处理它会更好吗? –