问题
Let's assume we create the file a.txt.gz
as follows:
$ echo "foobar" > a.txt
$ gzip a.txt
I intend to use zlib-conduit in order to emulate zcat
in Haskell.
I'm looking for a simple example that can also be applied to bzlib-conduit.
Note: This question was answered immediately in a Q&A-Style. Therefore it intentionally does not show any research effort.
回答1:
If you intend to work with conduit
s, I highly recommend to read the excellent Conduit overview by Michael Snoyman and the FP Complete tutorial on this topic first.
I've turned on my -vv
flag to make this suitable for Haskell beginners (like myself).
You need three things:
- A file source
- A zlib decompression filter
- A stdout sink
Let's start off with this simple file copy example:
import Data.Conduit (runResourceT, ($$))
import qualified Data.Conduit.Binary as CB
import Data.Conduit.Zlib
main = do
runResourceT $ CB.sourceFile "input.txt" $$ CB.sinkFile "output.txt"
What do we need to modify here?
- The input filename is not
a.txt.gz
- zlib decompressor is missing
- We want to output to stdout, not to
output.txt
Indeed the decompress documentation contains an example of how to decompress.
Note that you can't use decompress
for gzip
-generated files. decompress
decompresses .Z
files generated by the old compress
UNIX program.
After modifying the above example we get:
import Data.Conduit (runResourceT, ($$), ($=))
import qualified Data.Conduit.Binary as CB
import Data.Conduit.Zlib
import System.IO
main = do
runResourceT $ CB.sourceFile "a.txt.gz" $= ungzip $$ CB.sinkHandle stdout
The difference when using bzlib-conduit
is minimal:
import Data.Conduit (runResourceT, ($$), ($=))
import qualified Data.Conduit.Binary as CB
import Data.Conduit.BZlib
import System.IO
main = do
runResourceT $ CB.sourceFile "a.txt.bz2" $= bunzip2 $$ CB.sinkHandle stdout
来源:https://stackoverflow.com/questions/21359525/haskell-bzlib-conduit-zlib-conduit-example