Ответ 1
writeFile :: FilePath -> String -> IO ()
String
. Это ваша проблема, прямо здесь. String
- для текста в Юникоде. Попытка хранить двоичные данные в нем приведет к коррупции. В этом случае неясно, выполняется ли коррупция с помощью simpleHTTP
или writeFile
, но в конечном итоге это неважно. Вы используете неправильный тип, и что-то искажает данные при столкновении с байтами, которые не образуют допустимую кодировку в формате Юникода.
Что касается исправления этого, более новые версии HTTP
являются полиморфными по типу возвращаемого значения и могут обрабатывать возврат необработанных байтов в ByteString
. Вам просто нужно изменить способ записи байтов в файл, чтобы он не сделал вывод, что вы хотите String
.
import qualified Data.ByteString as B
import Network.HTTP
import Network.URI (parseURI)
main = do
jpg <- get "http://www.irregularwebcomic.net/comics/irreg2557.jpg"
B.writeFile "irreg2557.jpg" jpg
where
get url = let uri = case parseURI url of
Nothing -> error $ "Invalid URI: " ++ url
Just u -> u in
simpleHTTP (defaultGETRequest_ uri) >>= getResponseBody
Конструкция для получения полиморфного запроса немного неуклюжа. Если проблема № 1 будет исправлена, то использование getRequest url
будет достаточным.