Dlaczego mmap Pythona nie działa z dużymi plikami?

[Edytuj: Ten problem dotyczy tylko systemów 32-bitowych. Jeśli Twój komputer, Twój system operacyjny i implementacja Pythona są 64-bitowe, wtedy duże pliki działają niezawodnie i są niezwykle wydajne.]

Piszę moduł, który między innymi umożliwia bitowy dostęp do odczytu plików. Pliki mogą być potencjalnie duże (setki GB), więc napisałem prostą klasę, która pozwala mi traktować plik jak ciąg i ukrywa wszystkie poszukiwania i czytanie.

W tym czasie pisałem moją klasę wrappera, nie wiedziałem omoduł mmap. Po przeczytaniu dokumentacji dla mmap pomyślałem„Świetnie - to jest właśnie to, czego potrzebowałem, wyjmę swój kod i zastąpię go mmap. Prawdopodobnie jest znacznie bardziej wydajny i zawsze dobrze jest usunąć kod”.

Problem polega na tym, że mmap nie działa dla dużych plików! Jest to dla mnie bardzo zaskakujące, ponieważ myślałem, że to chyba najbardziej oczywista aplikacja. Jeśli plik jest większy niż kilka gigabajtów, otrzymujęEnvironmentError: [Errno 12] Cannot allocate memory. Dzieje się tak tylko w przypadku 32-bitowej kompilacji Pythona, więc wydaje się, że brakuje przestrzeni adresowej, ale nie mogę znaleźć żadnej dokumentacji na ten temat.

Mój kod jest po prostu

f = open('somelargefile', 'rb')
map = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)

Więc moje pytanie jestCzy brakuje mi tutaj czegoś oczywistego? Czy istnieje sposób na to, aby mmap działał przenośnie na dużych plikach, czy powinienem wrócić do mojego naiwnego opakowania plików?

Aktualizacja: Wydaje się, że istnieje wrażenie, że mmap Pythona powinien mieć takie same ograniczenia jak mmap POSIX. Aby lepiej wyrazić moją frustrację, jest prosta klasa, która ma niewielką część funkcjonalności mmap.

import os

class Mmap(object):
    def __init__(self, f):
        """Initialise with a file object."""
        self.source = f

    def __getitem__(self, key):
        try:
            # A slice
            self.source.seek(key.start, os.SEEK_SET)
            return self.source.read(key.stop - key.start)
        except AttributeError:
            # single element
            self.source.seek(key, os.SEEK_SET)
            return self.source.read(1)

Jest tylko do odczytu i nie robi nic szczególnego, ale mogę to zrobić tak samo, jak w przypadku mmap:

map2 = Mmap(f)
print map2[0:10]
print map2[10000000000:10000000010]

poza tym, że nie ma ograniczeń dotyczących rozmiaru plików. Niezbyt trudne ...

questionAnswers(8)

yourAnswerToTheQuestion