2009-09-16 26 views
6

Miễn là chúng tôi biết rằng tất cả tệp sẽ được tải trong bộ nhớ và chúng tôi có thể đủ khả năng, những hạn chế (nếu có) hoặc giới hạn (nếu có) là tải toàn bộ tệp (có thể là tệp nhị phân) trong một con trăn biến. Nếu điều này là kỹ thuật có thể, nên tránh điều này, và tại sao?Chúng tôi có thể sử dụng biến số python để giữ toàn bộ tệp không?

Về mối quan tâm về kích thước tệp, kích thước tối đa nên giải pháp này là bao nhiêu? Và tại sao ?

Mã tải thực tế có thể là mã được đề xuất trong this stackoverflow entry.

Mẫu mã là:

def file_get_contents(filename): 
    with open(filename) as f: 
     return f.read() 

content = file_get_contents('/bin/kill') 

... code manipulating 'content' ... 

[EDIT] Mã thao tác mà nói đến cái tâm (nhưng có lẽ không thích hợp) là tiêu chuẩn danh sách/chuỗi nhà khai thác (dấu ngoặc vuông, '+' dấu hiệu) hoặc một số chuỗi các toán tử ('len', 'trong' toán tử ', đếm', 'endswith'/'startswith', 'split', 'translation' ...).

Trả lời

6

Khi bạn nhận được phản hồi tốt, có vẻ như không ai trả lời câu hỏi này của bạn (thường xảy ra khi bạn đặt nhiều câu hỏi trong câu hỏi; -) ...:

Về mối quan tâm về kích thước tệp, với những gì kích thước tối đa, giải pháp này phải là bị giới hạn ?. Và tại sao ?

Điều quan trọng nhất là, bao nhiêu RAM vật lý có thể quá trình Python cụ thể này thực sự sử dụng (những gì được gọi là "làm việc thiết lập"), mà không quá mức xử phạt các khía cạnh khác của hiệu suất tổng thể của hệ thống. Nếu bạn vượt quá RAM vật lý cho "bộ làm việc" của mình, bạn sẽ được phân trang và hoán đổi vào đĩa, và hiệu suất của bạn có thể nhanh chóng bị suy giảm (tới trạng thái được gọi là "đập" về cơ bản là tất cả các chu kỳ có sẵn sẽ nhiệm vụ nhận được các trang trong và ngoài, và số lượng không đáng kể của công việc thực tế thực sự có thể được thực hiện).

Trong tổng số đó, một số tiền khá khiêm tốn (nói một vài MB nói chung) có thể sẽ được đưa lên bằng mã thực thi (các tệp thực thi của Python, DLL hoặc .so) và bytecode và hỗ trợ chung datastructures đang tích cực cần thiết trong bộ nhớ; trên một máy hiện đại tiêu biểu không thực hiện các nhiệm vụ quan trọng hoặc khẩn cấp khác, bạn có thể bỏ qua chi phí này so với gigabyte RAM mà bạn có sẵn (mặc dù tình hình có thể khác trên các hệ thống nhúng, vv).

Tất cả phần còn lại có sẵn cho dữ liệu của bạn - bao gồm tệp này bạn đang đọc vào bộ nhớ, cũng như bất kỳ cấu trúc dữ liệu quan trọng nào khác. "Sửa đổi" dữ liệu của tệp thường có thể mất gấp đôi bộ nhớ (kích thước của nội dung của tệp) (nếu bạn đang giữ nó trong một chuỗi) - tất nhiên, nếu bạn đang giữ một bản sao của dữ liệu cũ cũng như tạo bản sao/phiên bản sửa đổi mới. Vì vậy, đối với "chỉ đọc" sử dụng trên một máy 32-bit hiện đại điển hình với, nói, 2GB RAM tổng thể, đọc vào bộ nhớ (nói) 1,5 GB nên không có vấn đề; nhưng nó sẽ phải được ít hơn đáng kể 1 GB nếu bạn đang làm "sửa đổi" (và thậm chí ít hơn nếu bạn có cấu trúc dữ liệu quan trọng khác trong bộ nhớ!). Tất nhiên, trên một máy chủ chuyên dụng với một bản dựng 64 bit của Python, một hệ điều hành 64 bit và RAM 16 GB, các giới hạn thực tế trước rất khác nhau - xấp xỉ tỷ lệ với số lượng RAM khác nhau thực tế.

Ví dụ: văn bản Kinh thánh của King James có thể tải xuống here (giải nén) là khoảng 4,4 MB; vì vậy, trong một máy có RAM 2 GB, bạn có thể giữ khoảng 400 bản sao đã được sửa đổi một chút trong bộ nhớ (nếu không có gì khác yêu cầu bộ nhớ), nhưng, trong một máy có RAM 16 (có sẵn và địa chỉ), bạn có thể giữ hơn 3000 bản sao như vậy.

11
  • Vâng, bạn có thể
  • Hạn chế duy nhất là sử dụng bộ nhớ, và có thể cũng tăng tốc nếu các tập tin lớn.
  • Kích thước tệp phải được giới hạn trong số lượng bộ nhớ bạn có trong bộ nhớ.

Nói chung, có nhiều cách tốt hơn để làm điều đó, nhưng đối với các tập lệnh một lần mà bạn biết bộ nhớ không phải là vấn đề, chắc chắn.

3

Vấn đề duy nhất bạn có thể gặp phải là mức tiêu thụ bộ nhớ: Các chuỗi trong Python là không thay đổi. Vì vậy, khi bạn cần thay đổi một byte, bạn cần sao chép chuỗi cũ:

new = old[0:pos] + newByte + old[pos+1:] 

Điều này cần gấp ba lần bộ nhớ của old.

Thay vì chuỗi, bạn có thể sử dụng array. Những cung cấp hiệu suất tốt hơn nhiều nếu bạn cần phải sửa đổi các nội dung và bạn có thể tạo chúng một cách dễ dàng từ một chuỗi.

4
with open(filename) as f: 

Điều này chỉ hoạt động trên Python 2.x trên Unix. Nó sẽ không làm những gì bạn mong đợi trên Python 3.x hoặc trên Windows, vì cả hai đều vẽ một sự phân biệt mạnh giữa văn bản và các tệp nhị phân. Nó tốt hơn để xác định rằng tập tin là nhị phân, như thế này:

with open(filename, 'rb') as f: 

này sẽ tắt quy đổi CR/LF của OS trên Windows, và sẽ buộc Python 3.x để trả về một mảng byte chứ không phải là các ký tự Unicode.

Đối với phần còn lại của câu hỏi của bạn, tôi đồng ý với câu trả lời của Lennart Regebro (chưa được chỉnh sửa).

0

Có bạn có thể cung cấp tệp đủ nhỏ-. Nó thậm chí còn rất pythonic để chuyển đổi trở lại từ read() thành bất kỳ container/iterable kiểu như với nói, string.split(), cùng với các tính năng lập trình chức năng liên quan để tiếp tục điều trị tập tin "cùng một lúc".

1

Bạn cũng có thể sử dụng tính năng v3 Python:

>>> ''.join(open('htdocs/config.php', 'r').readlines()) 
"This is the first line of the file.\nSecond line of the file" 

đọc thêm ở đây http://docs.python.org/py3k/tutorial/inputoutput.html

+1

Xem bình luận khác của tôi, spam bài viết cũ với câu trả lời trùng lặp là không mang tính xây dựng. – Kev

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