如何使用Haskell LibZip编写zip文件?

时间:2013-10-01 06:43:33

标签: haskell zip

我试图在Haskell中使用LibZip找出一个简单的任务:如何打开存档foo.zip,解压缩,重新压缩,并将其保存到新存档{ {1}}?使用Zip库,这很简单:

bar.zip
另一方面,LibZip没有提供明确的方法(我可以看到)。它似乎只能用{-# LANGUAGE OverloadedStrings #-} import Codec.Archive.Zip (toArchive, fromArchive) import qualified Data.ByteString.Lazy as B import System.Environment saveZipAs :: FilePath -> FilePath -> IO () saveZipAs source dest = do arch <- fmap toArchive $ B.readFile source putStrLn "Archive info: " >> print arch B.writeFile dest $ fromArchive arch 实例化一个zip文件(这本身就是一个问题,因为你要打开的文件可能不在磁盘上),我看不到办法执行任何类型的“另存为”操作,也不要将压缩字节提取为withArchive或其他(如Zip中)。 LibZip据说比Zip更快,所以我想至少尝试一下,但它看起来更加模糊(并且也不纯净,随身携带ByteString,它实际上只在开始时才需要并结束,如果有的话)。谁能给我一些提示?

附注:对于人们如何花费如此大量的时间来编写一个库,只是为了记录它如此糟糕以至于没有人可以使用它,这真的令人难以置信。图书馆作家,请不要这样做!

1 个答案:

答案 0 :(得分:4)

你的链接是某个旧版本的库,并且该库的最后一个版本似乎有haddock编译错误。

以下是较新版本的文件阅读功能:

http://hackage.haskell.org/package/LibZip-0.10.2/docs/Codec-Archive-LibZip.html#g:3

反向过程似乎是addFile / sourceBuffer及相关功能。

以下是zip重新包装的完整源代码:

import Codec.Archive.LibZip
import Codec.Archive.LibZip.Types

main = readZip "foo.zip" >>= writeZip "bar.zip"

readZip :: FilePath -> IO [(FilePath, ZipSource)]
readZip zipName = withArchive [] zipName $ do
        nn <- fileNames []
        ss <- mapM (\n -> sourceFile n 0 (-1)) nn
        return $ zip nn ss

writeZip :: FilePath -> [(FilePath, ZipSource)] -> IO ()
writeZip zipName zipContent = withArchive [CreateFlag] zipName $ do
        mapM_ (uncurry addFile) zipContent

仍然可以完成很少的重构:liftM2 zip可以在readZip中使用,.中可以使用功能组合writeZip