Скачивание больших файлов из интернета в Haskell
Есть ли какие-либо предложения о том, как скачать большие файлы в Haskell? Я полагаю, что Http.Conduit - это хорошая библиотека для этого. Однако как это решить? В документации есть пример, но он не подходит для загрузки больших файлов, он просто загружает файл:
import Data.Conduit.Binary (sinkFile)
import Network.HTTP.Conduit
import qualified Data.Conduit as C
main :: IO ()
main = do
request <- parseUrl "http://google.com/"
withManager $ \manager -> do
response <- http request manager
responseBody response C.$$+- sinkFile "google.html"
Что я хочу, так это иметь возможность загружать большие файлы и не исчерпывать ОЗУ, например, делать это эффективно с точки зрения производительности и т. Д. Предпочтительно иметь возможность продолжать загружать их "позже", что означает "какая-то часть сейчас, другая часть позже".,
Я также нашел пакет download-curl на hackage, но я не уверен, что он подходит, или даже то, что он загружает файлы по частям так, как мне нужно.
2 ответа
Network.HTTP.Conduit
предоставляет три функции для выполнения запроса:
Из трех функций первые две функции заставят все тело ответа жить в памяти. Если вы хотите работать в постоянной памяти, используйте http
функция. http
Функция дает вам доступ к потоковому интерфейсу через ResumableSource
Пример, который вы предоставили в своем коде, использует чередующийся ввод-вывод для записи тела ответа в файл в постоянном пространстве памяти. Таким образом, вам не хватит памяти при загрузке большого файла.
Это работает для меня:
import Control.Monad.Trans.Resource (runResourceT)
import Data.Conduit.Combinators (sinkFile)
import Network.HTTP.Conduit (parseRequest)
import Network.HTTP.Simple (httpSink)
downloadFile :: String -> IO ()
downloadFile url = do
request <- parseRequest url
runResourceT $ httpSink request $ \_ -> sinkFile "tmpfile"
Я согласен, что немного странно, что он занимает четыре разных модуля (и из 3-х пакетов:
conduit
,
resourcet
а также
http-conduit
) для такой задачи.