我试图在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
,它实际上只在开始时才需要并结束,如果有的话)。谁能给我一些提示?
附注:对于人们如何花费如此大量的时间来编写一个库,只是为了记录它如此糟糕以至于没有人可以使用它,这真的令人难以置信。图书馆作家,请不要这样做!
答案 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
。