Работа с большими файлами в Haskell

У меня есть большой файл (4+ гигабайта), скажем так, 4 байта с плавающей запятой. Я хотел бы рассматривать его как список в том смысле, что я хотел бы иметь возможность использовать карту, фильтр, складку и т. д. Однако вместо создания нового списка с выводом я хотел бы записать вывод обратно в файл, и, таким образом, нужно загрузить только небольшую часть файла в память. Вы могли бы сказать, что я называю тип MutableFileList

Кто-нибудь уже сталкивался с этой ситуацией? Вместо того, чтобы заново изобретать колесо, мне было интересно, есть ли хакерский способ справиться с этим?


person Jonathan Fischoff    schedule 18.12.2009    source источник


Ответы (3)


Вы не должны рассматривать его как [Double] или [Float] в памяти. Что вы можете сделать, так это использовать один из типов упакованных массивов, похожих на списки, таких как uvector/vector/... в компании с mmapFile или readFile, чтобы загружать фрагменты файла за раз и обрабатывать их. Или используйте ленивые упакованные массивы, эквивалентные ленивым байтовым строкам.

person Don Stewart    schedule 18.12.2009
comment
Вы становитесь таким же известным, как Джон Скит в сообществе Haskell. Вас проголосовали только за публикацию. :п - person Rayne; 18.12.2009

Это должно быть вам очень полезно. Вы можете использовать readFile и writeFile для того, что вам нужно сделать, и все делается лениво. Он хранит данные в памяти только тогда, когда они все еще используются, поэтому вы можете читать, обрабатывать и записывать файл, не перегружая свой компьютер.

person Rayne    schedule 18.12.2009
comment
Хм, я не понимал, что значения будут вытеснены из памяти. Хорошо, я попробую. - person Jonathan Fischoff; 18.12.2009

Вы можете использовать mmap для сопоставления файла с памятью, а затем обработать его. Существует модуль mmap, который обещает чтение и запись mmap-файлов и даже может работать с лениво файлы, но я не пробовал.

Интерфейс для записи в сопоставленный файл выглядит довольно низкоуровневым, поэтому вам придется создавать собственные абстракции или работать с Foreign.Ptr и тому подобное.

person sth    schedule 18.12.2009
comment
@Jonathan: Ты уверен, что это не сработает? В документации говорится, что модуль использует CreateFileMapping и MapViewOfFile, оба из которых имеют 64-битные параметры размера/смещения файла, поэтому эти вызовы API должны работать для файлов любого размера (например, msdn.microsoft.com/en-us/library/ ). Модуль тогда как-то ломает этот функционал? - person sth; 18.12.2009
comment
@sth Честно говоря, я точно не знаю. Я исхожу из того, что прочитал в сети. Я получил это ограничение потока о файлах с отображением памяти на этом сайте. Я не видел ничего в MSDN, в котором бы указывались требования к размеру, но я не думаю, что программа сможет получить более 2 ГБ памяти, независимо от того, как вы ее нарежете. Я вроде чего наоборот, файл отображал память :) - person Jonathan Fischoff; 18.12.2009