2009-12-08 36 views
10

有一个文件,我想确保不增长大于2 GB(因为它必须运行在使用ext 2的系统上)。考虑到我将在两次检查之间写入这个文件,检查文件大小的好方法是什么?特别是,我是否需要担心尚未写入磁盘的缓冲,未刷新的更改?如何确定Python中打开文件的大小?

+2

是否有一个原因,你不能只是跟踪文件的大小自己的 - 那就是,看大小是什么,当你打开它,增加当你写一个计数器?不是特别优雅,但它应该工作。 – 2009-12-08 14:39:23

+0

我想这可能是我没有想到的......我也可以尝试。 – 2009-12-08 14:40:49

+0

虽然这不是低效的吗? – 2009-12-08 14:51:44

回答

4

你可以开始是这样的:如果你不写文件

>>> f = TrackedFile('palindrome.txt', 'w') 
>>> f.size 
0 
>>> f.write('A man a plan a canal ') 
>>> f.size 
21 
>>> f.write('Panama') 
27 

显然,这不工作:

class TrackedFile(file): 
    def __init__(self, filename, mode): 
     self.size = 0 
     super(TrackedFile, self).__init__(filename, mode) 
    def write(self, s): 
     self.size += len(s) 
     super(TrackedFile, self).write(s) 

然后,你可以使用它像这样从头开始,但你可以调整你的方法来处理初始数据。您可能还需要重写一些其他方法:例如,writelines

无论编码如何,它都可以工作,因为字符串只是字节序列。

>>> f2 = TrackedFile('palindrome-latin1.txt', 'w') 
>>> f2.write(u'A man a plan a canál '.encode('latin1') 
>>> f3 = TrackedFile('palindrome-utf8.txt', 'w') 
>>> f3.write(u'A man a plan a canál '.encode('utf-8')) 
>>> f2.size 
21 
>>> f3.size 
22 
+0

+1:这是一个非常聪明的想法。我喜欢! – jathanism 2009-12-08 15:50:29

+0

这不是真的。它使用ASCII,ISO1559和UTF-8,结果将是相同的,但磁盘大小不会。 – 2009-12-09 17:25:33

+0

否。如果使用实际的字符串,它也适用于其他编码。应用修改来演示。 – jcdyer 2009-12-09 17:32:33

15

也许不是你想要的,但我会建议它。

import os 
a = os.path.getsize("C:/TestFolder/Input/1.avi") 

另外一个打开的文件,你可以使用fstat功能,它可以在一个打开的文件中。它需要一个整数的文件句柄,不是一个文件对象,所以你必须使用的fileno方法的文件对象:

a = open("C:/TestFolder/Input/1.avi") 
b = os.fstat(a.fileno()).st_size 
2

最可靠的是创建一个包装类,当你打开它会检查文件的大小,跟踪写入和查找操作,根据这些操作计算当前大小并防止超出大小限制。

2

或者,如果文件已经打开:

>>> fsock = open('/etc/hosts', 'rb').read() 
>>> len(fsock) 
444 

这是该文件的字节数是。

6

os.fstat(file_obj.fileno()).st_size应该做的伎俩。我认为它会返回写入的字节。如果你担心缓冲,你总是可以在手边冲水。

+0

也可以在追加模式下工作!谢谢。是的,我会在打电话之前冲洗。 – 2017-10-06 22:07:43

4

我不熟悉python,但是没有流对象(或打开文件时得到的任何东西)有一个包含流的当前位置的属性?

与您使用C函数ftell()或.NET中的Stream.Position类似。

显然,只有当您位于流的末尾时,才能正常工作。

这种方法的好处是您不必关闭文件或担心未刷新的数据。

+0

'filehandle.tell()'确实显示打开的文件中的字节数,并且可以在写或附加模式下工作。不知道为什么所有这些更复杂的答案都得到了提升。 – hurfdurf 2015-07-30 17:17:14

+1

@hurfdurf不,'f.tell()'似乎在追加模式下不能可靠地工作。除非你第一个'f.seek(0,2)'。我不知道为什么。 – 2017-10-06 21:51:49

4

虽然这是一个老问题,但我认为Isak有最简单的解决方案。以下是如何做到这一点在Python:

# Assuming f is an open file 
>>> pos = f.tell() # Save the current position 
>>> f.seek(0, 2) # Seek to the end of the file 
>>> length = f.tell() # The current position is the length 
>>> f.seek(pos) # Return to the saved position 
>>> print length 
1024 
+0

我认为在第一行(保存当前位置),你应该使用f.tell(),而不是seek(),这会导致异常,因为seek()需要至少1个参数。 – Jkm 2017-06-13 03:12:30

+0

@Jkm是的,你是对的!不知道我是如何错过的。谢谢! – Trenton 2017-06-13 14:38:31

+0

这将正确计算文件大小,但由于[tell in append mode](https://stackoverflow.com/questions/31680677/)中的已知问题而无法正确恢复位置。 – 2017-10-06 22:06:02

相关问题