2012-04-06 39 views
5

私は圧縮することができるファイル読み取りにこのコードスニペットを書いた:それはうまくコンパイル解凍IOErrorを取得するにはどうすればよいですか?

import Codec.Compression.GZip 
import IO -- using IO.try 

read file = do 
    let f = L.readFile file 
    let c = fmap decompress $ f 

    unzipped <- try c 

    case unzipped of 
    Right b -> return b 
    Left _ -> f 

を、これは非圧縮ファイルを扱うための有効な方法ではないようです。圧縮ファイルのコードを実行すると、素敵に動作しますが、圧縮されていないファイルが例外で失敗します

*** Exception: Codec.Compression.Zlib: incorrect header check 

これを可能にする方法上の任意のアイデア?

+0

は 'IO.try'は推奨されていません(私はあなたがData.ByteString.LazyはL.の資格インポートしていると推定します) ... Control.Exception.tryはどうでしょうか? http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Exception.html#v:try –

+2

さらに「IO.try」は、純粋なコードから例外をキャッチしません'Control.Exception.try'は行います。 – dave4420

答えて

4

Codec.Compression.Zlib.Internalをインポートする必要があります。特に、“Low-level API to get explicit error reports”というタイトルのセクションに注意してください。

あなたは(未テストに注意してください)このようなものを使用したいと思うでしょう:

import qualified Codec.Compression.Zlib.Internal as Z 
import Control.Arrow (right) 

decompressWithoutExceptions :: L.ByteString -> Either Z.DecompressError L.ByteString 
decompressWithoutExceptions = finalise 
          . Z.foldDecompressStream cons nil err 
          . Z.decompressWithErrors Z.gzipFormat Z.defaultDecompressParams 
    where err errorCode errorString = Left errorCode 
     nil = Right [] 
     cons chunk = right (chunk :) 
     finalise = right L.fromChunks 

+0

うわー...ここで何が起こっているのか説明できますか? :) – fho

+0

気にしないで、それは動作しますか? (どのビットを理解していないのですか?decompressWithErrors'と 'foldDecompressStream'などについては、私がリンクしているドキュメントの中で説明されています(明らかに十分ではありませんか?) – dave4420

+0

このfinalizeメソッドはどこから来たのですか?私はhayooで見つけられませんでした。 – fho

2

spoonを参照すると、例外がスローされた場合はNothingが得られます。

関連する問題