我编写了这段代码片段来读取可能被压缩的文件:
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
Run Code Online (Sandbox Code Playgroud)
它编译得很好,但似乎这不是处理未压缩文件的有效方法.在压缩文件上运行代码效果很好,但未压缩文件失败并出现异常:
*** Exception: Codec.Compression.Zlib: incorrect header check
Run Code Online (Sandbox Code Playgroud)
有关如何实现这一点的任何想法?
您需要导入Codec.Compression.Zlib.Internal。请特别注意标题为\xe2\x80\x9cLow-level API to get Explicit error reports\xe2\x80\x9d 的部分。
\n\n你会想要使用这样的东西(注意未经测试):
\n\nimport qualified Codec.Compression.Zlib.Internal as Z\nimport Control.Arrow (right)\n\ndecompressWithoutExceptions :: L.ByteString -> Either Z.DecompressError L.ByteString\ndecompressWithoutExceptions = finalise\n . Z.foldDecompressStream cons nil err\n . Z.decompressWithErrors Z.gzipFormat Z.defaultDecompressParams\n where err errorCode errorString = Left errorCode\n nil = Right []\n cons chunk = right (chunk :)\n finalise = right L.fromChunks\nRun Code Online (Sandbox Code Playgroud)\n\n(我假设您已导入符合 L 资格的 Data.ByteString.Lazy。)
\n