2009-12-08 28 views
10

Có một tệp mà tôi muốn đảm bảo không phát triển lớn hơn 2 GB (vì nó phải chạy trên hệ thống sử dụng ext 2). Một cách tốt để kiểm tra kích thước của tập tin mang trong tâm trí là tôi sẽ được ghi vào tập tin này ở giữa kiểm tra là gì? Đặc biệt, tôi có cần phải lo lắng về các thay đổi đệm, không bị xóa mà chưa được ghi vào đĩa chưa?Làm cách nào để xác định kích thước tệp mở bằng Python?

+2

Có lý do bạn không thể chỉ theo dõi kích thước tệp - nghĩa là xem kích cỡ khi bạn mở và tăng bộ đếm khi bạn viết ?Không đặc biệt thanh lịch, nhưng nó sẽ hoạt động. –

+0

Tôi cho rằng đó là một khả năng tôi đã không nghĩ đến ... Tôi cũng có thể thử điều đó. –

+0

Đó không phải là không hiệu quả như địa ngục mặc dù? –

Trả lời

4

Bạn có thể bắt đầu với một cái gì đó như thế này:

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) 

Sau đó, bạn có thể sử dụng nó như thế này:

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

Rõ ràng, triển khai này không có tác dụng nếu bạn không phải viết các tập tin từ đầu, nhưng bạn có thể điều chỉnh phương thức __init__ để xử lý dữ liệu ban đầu. Bạn cũng có thể cần phải ghi đè lên một số phương thức khác: ví dụ: writelines.

Tác phẩm này không phân biệt mã hóa vì chuỗi chỉ là chuỗi byte.

>>> 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: Đó là một ý tưởng thực sự thông minh. Tôi thích nó! – jathanism

+0

Điều đó không thực sự. Nó bạn sử dụng ASCII, ISO1559 và UTF-8, kết quả sẽ giống nhau, nhưng kích thước trên đĩa sẽ không được. –

+0

Không. Nó cũng hoạt động với các mã hóa khác, nếu bạn sử dụng các chuỗi thực tế. Trả lời sửa đổi để chứng minh. – jcdyer

15

Có lẽ không phải những gì bạn muốn, nhưng tôi sẽ đề xuất nó.

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

Cách khác để mở tệp, bạn có thể sử dụng chức năng fstat, có thể được sử dụng trên tệp được mở. Phải mất một tay cầm tập số nguyên, không phải là một đối tượng tập tin, vì vậy bạn phải sử dụng phương pháp fileno trên đối tượng file:

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

đáng tin cậy Hầu hết sẽ tạo ra một lớp gói mà sẽ kiểm tra kích thước tập tin khi bạn mở nó, theo dõi hoạt động viết và tìm kiếm, đếm kích thước hiện tại dựa trên các hoạt động đó và ngăn không cho vượt quá giới hạn kích thước.

2

Hoặc, nếu các tập tin đã được mở:

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

Đó là bao nhiêu byte file là.

6

os.fstat(file_obj.fileno()).st_size nên thực hiện thủ thuật. Tôi nghĩ rằng nó sẽ trả về các byte được viết. Bạn luôn có thể xả nước trước khi bàn tay nếu bạn lo lắng về việc lưu vào bộ đệm.

+0

Và cũng hoạt động ở chế độ phụ thêm! Cảm ơn bạn. Và vâng, tôi sẽ tuôn ra trước khi gọi điều này. –

4

Tôi không quen với python, nhưng không phải đối tượng luồng (hoặc bất kỳ thứ gì bạn nhận được khi mở tệp) có thuộc tính chứa vị trí hiện tại của luồng không?

Tương tự như những gì bạn nhận được với chức năng ftell() C hoặc Stream.Position trong .NET.

Rõ ràng, điều này chỉ hoạt động nếu bạn được đặt ở cuối luồng, bạn đang ở đâu nếu bạn hiện đang viết thư cho nó.

Lợi ích của cách tiếp cận này là bạn không phải đóng tệp hoặc lo lắng về dữ liệu chưa được lưu.

+0

'filehandle.tell()' thực sự hiển thị số byte trong tệp đã mở và hoạt động ở chế độ ghi hoặc nối. Không chắc tại sao tất cả những câu trả lời phức tạp hơn này lại được bình chọn. – hurfdurf

+1

@hurfdurf Không, 'f.tell()' dường như không hoạt động đáng tin cậy trong chế độ nối thêm. Trừ khi bạn đầu tiên 'f.seek (0,2)'. Tôi không biết tại sao. –

4

Mặc dù đây là câu hỏi cũ, tôi nghĩ rằng Isak có giải pháp đơn giản nhất. Dưới đây là cách thực hiện trong 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

Tôi nghĩ rằng trong dòng đầu tiên (lưu vị trí hiện tại), bạn nên sử dụng f.tell(), chứ không phải tìm kiếm(), điều này sẽ gây ra một ngoại lệ vì tìm kiếm() cần ít nhất 1 đối số. – Jkm

+0

@Jkm Vâng, bạn đã đúng! Không chắc tôi đã bỏ lỡ điều đó như thế nào. Cảm ơn! – Trenton

+0

Điều này sẽ tính toán kích thước tệp một cách chính xác, nhưng sẽ không khôi phục vị trí chính xác do các sự cố đã biết với [cho biết trong chế độ nối thêm] (https://stackoverflow.com/questions/31680677/). –

Các vấn đề liên quan