2012-06-22 11 views
5

Trong Python 2.7, khi tôi tải tất cả dữ liệu từ một tập tin văn bản của 2.5GB vào bộ nhớ để chế biến nhanh như thế này:Python tải 2GB file văn bản vào bộ nhớ

>>> f = open('dump.xml','r') 
>>> dump = f.read() 

Tôi đã nhận lỗi sau:

Python(62813) malloc: *** mmap(size=140521659486208) failed (error code=12) 
*** error: can't allocate region 
*** set a breakpoint in malloc_error_break to debug 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
MemoryError 

Tại sao Python cố phân bổ 140521659486208 byte bộ nhớ cho dữ liệu 2563749237 byte? Làm thế nào để sửa mã để làm cho nó tải tất cả các byte?

Tôi đang rảnh khoảng 3 GB RAM. Tệp này là một tệp Wiktionary xml dump.

+7

Tại sao bạn không phân tích cú pháp XML một cách tuyến tính mà không tải nguồn vào bộ nhớ trước? – Alfe

+0

Tôi đã thử nó và nó đã cho tôi rất dài. Và vì tôi có rất nhiều RAM, tôi muốn tải mọi thứ vào RAM để làm cho nó nhanh hơn. – pckben

+0

Bao nhiêu ram? 64 hoặc 32 bit? – joslinm

Trả lời

10

Nếu bạn sử dụng mmap, bạn sẽ có thể tải toàn bộ tệp vào bộ nhớ ngay lập tức.

import mmap 

with open('dump.xml', 'rb') as f: 
    # Size 0 will read the ENTIRE file into memory! 
    m = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ) #File is open read-only 

    # Proceed with your code here -- note the file is already in memory 
    # so "readine" here will be as fast as could be 
    data = m.readline() 
    while data: 
    # Do stuff 
    data = m.readline() 
+0

Tôi đã nhận 'mmap.error: [Errno 13] Quyền bị từ chối' đối với dòng có' m = mmap.mmap (..) ', làm cách nào để sửa lỗi? – pckben

+2

@pckben Đó là vì tệp đang mở ở chế độ chỉ đọc và mmap sẽ cố gắng ánh xạ đọc-ghi: thêm 'prot = mmap.PROT_READ' vào cuộc gọi' mmap.mmap' của bạn và bạn sẽ ổn. –

+1

Tuyệt. Nó đã làm việc! Bạn có quan tâm để giải thích những gì đã xảy ra? – pckben

0

Dựa trên một số googling nhanh chóng, tôi đã xem qua this forum post dường như giải quyết vấn đề mà bạn dường như đang gặp phải. Giả sử bạn đang chạy Mac hoặc Linux dựa trên mã lỗi, bạn có thể thử triển khai bộ sưu tập rác với gc.enable() hoặc gc.collect() như được đề xuất trong bài đăng trên diễn đàn.

+0

mã của tôi chỉ có 2 dòng như được đưa ra để tải dữ liệu vào bộ nhớ, không có đối tượng sống nào khác để thu thập rác. – pckben