2012-07-17 63 views
11

我試圖使用Network.HTTP模塊下載圖像並且收效甚微。Haskell Network.HTTP不正確地下載圖像

import Network.HTTP 

main = do 
    jpg <- get "http://www.irregularwebcomic.net/comics/irreg2557.jpg" 
    writeFile "irreg2557.jpg" jpg where 
     get url = simpleHTTP (getRequest url) >>= getResponseBody 

輸出文件顯示在當前目錄中,但是沒有根據鉻或短萃取濃縮咖啡顯示量。 Ristretto報告「解釋JPEG圖像文件時出錯(不是JPEG文件:以0c3 0xbf開頭)」。

回答

23
writeFile :: FilePath -> String -> IO() 

String。那就是你的問題,就在那裏。 String適用於unicode文本。試圖在其中存儲二進制數據將導致腐敗。在這種情況下,不清楚simpleHTTPwriteFile是否正在進行腐敗,但它最終並不重要。您使用的是錯誤的類型,並且遇到不構成有效Unicode編碼的字節時,某些內容會破壞數據。

至於解決這個問題,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 

獲得多態請求的構造有點笨拙。如果issue #1得到解決,那麼使用getRequest url就足夠了。

+2

你的回答稍微不正確,因爲getRequest返回一個Request_String,它阻止了它的多態性。我將編輯一個適合我的版本。 – 2012-07-17 04:59:28

+0

哎呦。接得好。這是一個愚蠢的錯誤。 – Carl 2012-07-17 15:52:42