Extracting single file from zip archive using Haskell

658 Views Asked by At

Using the zip-conduit library, I want to extract a single file (e.g. bar/foo.txt) from the ZIP archive.

The example on hackage only shows how to extract all files at once. How can I extract only a single file or a list of files?

Note: This question was answered using Q&A-style and therefore intentionally doesn't show any research effort!

1

There are 1 best solutions below

0
On BEST ANSWER

The official example applies extractFiles to the [FilePath] as returned by fileNames. You can simply apply it to a custom list of filenames:

import Codec.Archive.Zip (withArchive, extractFiles)
import System.Environment (getArgs)

main = do
    -- ZIP file name: First commandline arg
    zipPath:_ <- getArgs
    withArchive zipPath $
        extractFiles ["bar/foo.txt"] "."

This code will create a folder bar in the current working directory and extract the file foo.txt into said folder. If any such file already exists, it will be overwritten.

If you intend to extract to a custom filename (e.g. you want to extract foo.txt to your current working directory, not to the bar folder), you need to use conduits as shown in this example:

import Codec.Archive.Zip (withArchive, sourceEntry)
import System.Environment (getArgs)
import qualified Data.Conduit.Binary as CB

main = do
    -- ZIP file name: First commandline arg
    zipPath:_ <- getArgs
    withArchive zipPath $
        sourceEntry "bar/foo.txt" $ CB.sinkFile "foo.txt"

Instead of using CB.sinkFile you can use any other conduit sink.