Safe Haskell | None |
---|---|
Language | Haskell2010 |
This module is about stream-processing tar archives. It is currently
not very well tested. See the documentation of withEntries
for an usage sample.
- tar :: MonadResource m => ConduitM (Either FileInfo ByteString) ByteString m FileOffset
- tarEntries :: MonadResource m => ConduitM (Either Header ByteString) ByteString m FileOffset
- untar :: MonadThrow m => (FileInfo -> ConduitM ByteString o m ()) -> ConduitM ByteString o m ()
- untarWithFinalizers :: (MonadThrow m, MonadIO m) => (FileInfo -> ConduitM ByteString (IO ()) m ()) -> ConduitM ByteString c m ()
- restoreFile :: MonadResource m => FileInfo -> ConduitM ByteString (IO ()) m ()
- restoreFileInto :: MonadResource m => FilePath -> FileInfo -> ConduitM ByteString (IO ()) m ()
- withEntry :: MonadThrow m => (Header -> ConduitM ByteString o m r) -> ConduitM TarChunk o m r
- withEntries :: MonadThrow m => (Header -> ConduitM ByteString o m ()) -> ConduitM TarChunk o m ()
- headerFileType :: Header -> FileType
- headerFilePath :: Header -> FilePath
- tarFilePath :: MonadResource m => ConduitM FilePath ByteString m FileOffset
- filePathConduit :: MonadResource m => ConduitM FilePath (Either FileInfo ByteString) m ()
- createTarball :: FilePath -> [FilePath] -> IO ()
- writeTarball :: Handle -> [FilePath] -> IO ()
- extractTarball :: FilePath -> Maybe FilePath -> IO ()
- module Data.Conduit.Tar.Types
Basic functions
tar :: MonadResource m => ConduitM (Either FileInfo ByteString) ByteString m FileOffset Source #
Create a tar archive by suppying a stream of Left
FileInfo
s. Whenever a
file type is FTNormal
, it must be immediately followed by its content as
Right
ByteString
. The produced ByteString
is in the raw tar format and
is properly terminated at the end, therefore it should no be modified
afterwards. Returned is the total size of the bytestring as a FileOffset
.
tarEntries :: MonadResource m => ConduitM (Either Header ByteString) ByteString m FileOffset Source #
untar :: MonadThrow m => (FileInfo -> ConduitM ByteString o m ()) -> ConduitM ByteString o m () Source #
Just like withFileInfo
, but works directly on the stream of bytes.
untarWithFinalizers :: (MonadThrow m, MonadIO m) => (FileInfo -> ConduitM ByteString (IO ()) m ()) -> ConduitM ByteString c m () Source #
Just like untar
, except that each FileInfo
handling function can produce a finalizing
action, all of which will be executed after the whole tarball has been processed in the opposite
order. Very useful with restoreFile
and restoreFileInto
, since they restore direcory
modification timestamps only after files have been fully written to disk.
restoreFile :: MonadResource m => FileInfo -> ConduitM ByteString (IO ()) m () Source #
Restore files onto the file system. Produces actions that will set the modification time on the directories, which can be executed after the pipeline has finished and all files have been written to disk.
restoreFileInto :: MonadResource m => FilePath -> FileInfo -> ConduitM ByteString (IO ()) m () Source #
Restore all files into a folder. Absolute file paths will be turned into relative to the supplied folder.
withEntry :: MonadThrow m => (Header -> ConduitM ByteString o m r) -> ConduitM TarChunk o m r Source #
Process a single tar entry. See withEntries
for more details.
withEntries :: MonadThrow m => (Header -> ConduitM ByteString o m ()) -> ConduitM TarChunk o m () Source #
This function handles each entry of the tar archive according to the behaviour of the function passed as first argument.
Here is a full example function, that reads a compressed tar archive and for each entry that is a simple file, it prints its file path and SHA256 digest. Note that this function can throw exceptions!
import qualified Crypto.Hash.Conduit as CH import qualified Data.Conduit.Tar as CT import Conduit import Crypto.Hash (Digest, SHA256) import Control.Monad (when) import Data.Conduit.Zlib (ungzip) import Data.ByteString (ByteString) filedigests :: FilePath -> IO () filedigests fp = runConduitRes ( sourceFileBS fp -- read the raw file .| ungzip -- gunzip .| CT.untarChunks -- decode the tar archive .| CT.withEntries hashentry -- process each file .| printC -- print the results ) where hashentry :: Monad m => CT.Header -> Conduit ByteString m (FilePath, Digest SHA256) hashentry hdr = when (CT.headerFileType hdr == CT.FTNormal) $ do hash <- CH.sinkHash yield (CT.headerFilePath hdr, hash)
The hashentry
function handles a single entry, based on its first Header
argument.
In this example, a Consumer
is used to process the whole entry.
Note that the benefits of stream processing are easily lost when working with a Consumer
. For example, the following implementation would have used an unbounded amount of memory:
hashentry hdr = when (CT.headerFileType hdr == CT.FTNormal) $ do content <- mconcat <$> sinkList yield (CT.headerFilePath hdr, hash content)
Helper functions
headerFileType :: Header -> FileType Source #
headerFilePath :: Header -> FilePath Source #
Creation
tarFilePath :: MonadResource m => ConduitM FilePath ByteString m FileOffset Source #
Recursively tar all of the files and directories. There will be no
conversion between relative and absolute paths, so just like with GNU tar
cli tool, it may be necessary to setCurrentDirectory
in order to get the
paths relative. Using filePathConduit
directly, while modifying the
filePath
, would be another approach to handling the file paths.
filePathConduit :: MonadResource m => ConduitM FilePath (Either FileInfo ByteString) m () Source #
Turn a stream of file paths into a stream of FileInfo
and file
content. All paths will be decended into recursively.
Directly on files
:: FilePath | File name for the tarball |
-> [FilePath] | List of files and directories to include in the tarball |
-> IO () |
Uses tarFilePath
to create a tarball, that will recursively include the
supplied list of all the files and directories
:: FilePath | Filename for the tarball |
-> Maybe FilePath | Folder where tarball should be extract to. Default is the current path |
-> IO () |
Extract a tarball.
Types
module Data.Conduit.Tar.Types