2009-12-18 15 views
9

Ich habe eine große Datei (4+ Gigs), sagen wir mal, 4 Byte Floats. Ich möchte es als List behandeln, in dem Sinne, dass ich Map, Filter, Foldl usw. verwenden möchte. Anstatt jedoch eine neue Liste mit der Ausgabe zu erstellen, möchte ich die Ausgabe wieder in schreiben die Datei, und muss nur einen kleinen Teil der Datei im Speicher laden. Sie könnten sagen, was für ein Typ namens MutableFileListUmgang mit großen Dateien in Haskell

Hat jemand in dieser Situation vor gelandet? Anstatt das Rad neu zu erfinden, habe ich mich gefragt, ob es einen Hack'schen Weg gibt, damit umzugehen?

Antwort

1

Sie könnten mmap verwenden, um die Datei im Speicher abzubilden und dann zu verarbeiten. Es gibt eine mmap module, die read and write mmaped files verspricht und sogar mit lazy mapped Brocken von Dateien arbeiten kann, aber ich habe es nicht versucht.

Die Schnittstelle zum Schreiben in die abgebildete Datei scheint ziemlich niedrig zu sein, also müssten Sie Ihre eigenen Abstraktionen erstellen oder mit Foreign.Ptr und ähnlichem arbeiten.

+0

Funktioniert nicht mit Dateien über 2 GB auf Windows. –

+0

@ Jonathan: Sind Sie sicher, dass es nicht funktioniert? Die Dokumentation besagt, dass das Modul 'CreateFileMapping' und' MapViewOfFile' verwendet, beide mit den Dateigrößen/Offset-Parametern mit 64 Bit, so dass dieser API-Aufruf für Dateien beliebiger Größe funktionieren sollte (zB http://msdn.microsoft.com/ en-us/library/aa366761% 28VS.85, leichtgewichtig% 29.aspx). Unterbricht das Modul diese Funktionalität? – sth

+0

@sth Ehrlich gesagt weiß ich es nicht genau. Ich gehe weg, was ich im Netz lese. Ich habe diese Einschränkung eines Threads über Speicherkarten auf dieser Site erhalten. Ich habe nichts auf MSDN gesehen, das die Größenanforderungen in beide Richtungen spezifiziert, aber ich glaube nicht, dass ein Programm mehr als 2 GB Speicher bekommen kann, egal wie man es schneidet. Ich irgendwie, was die umgekehrte, file mapped Speicher :) –

9

This sollte für Sie ziemlich hilfreich sein. Sie können readFile und writeFile für das verwenden, was Sie tun müssen, und alles wird träge getan. Es speichert nur die Daten im Speicher, während sie noch verwendet werden, sodass Sie die Datei lesen, verarbeiten und schreiben können, ohne Ihren Computer in die Luft zu sprengen.

+0

Hmm, ich wusste nicht, dass die Werte aus dem Speicher geräumt werden würde. Okay, ich gebe das eine Chance. –

12

Sie sollten es nicht als [Double] oder [Float] im Speicher behandeln. Sie können einen der listenartig gepackten Array-Typen verwenden, z. B. uvector/vector/... in Verbindung mit mmapFile oder readFile, um Teile der Datei gleichzeitig zu übernehmen und zu verarbeiten. Oder verwenden Sie einen Lazy-gepackten Array-Typ, der faulen Bytestrings entspricht.

+1

Sie werden so prominent wie Jon Skeet in der Haskell-Community. Sie werden nur zum Posten hochgezählt. : p – Rayne