从文件到进程的haskell管道

从文件到进程的haskell管道,haskell,monads,monad-transformers,conduit,Haskell,Monads,Monad Transformers,Conduit,如何将文件流式传输到进程中 Data.Conduit.Binary.sourceFile :: MonadResource m => FilePath -> Producer m ByteString Data.Conduit.Process.sourceProcessWithStreams :: CreateProcess -> Producer IO ByteString -> Consumer ByteString IO a -> Consumer ByteS

如何将文件流式传输到进程中

Data.Conduit.Binary.sourceFile :: MonadResource m => FilePath -> Producer m ByteString
Data.Conduit.Process.sourceProcessWithStreams :: CreateProcess -> Producer IO ByteString -> Consumer ByteString IO a -> Consumer ByteString IO b -> IO (ExitCode, a, b)
唯一的
MonadResource
ResourceT
,尤其是
IO
不是
MonadResource

我可以看到有
sourceHandle
,它是
IO
,但如果可能的话,我宁愿不处理我自己的文件打开和关闭。此外,我想了解这个问题,以防我在另一个空间中了解它

还有
数据、导管、提升、分发

distribute :: (Monad (t (ConduitM b o m)), Monad m, Monad (t m), MonadTrans t, MFunctor t) => ConduitM b o (t m) () -> t (ConduitM b o m) () 
所以我会得到类似的东西

distribute $ sourceFile "foo" :: ResourceT (ConduitM i ByteString IO) ()

但是我不知道如何使用它。

因为您可以提供
CreateProcess
文件名,所以您可以使用
CreateProcess
的重定向功能甚至shell从已知文件名重定向stdin

这里有一些例子。请注意,在每种情况下,
wc
都会报告 文件
input
的统计信息,而不是提供的生产者(其 是空的生产者。)


由于您能够提供
CreateProcess
,因此可以使用
CreateProcess
的重定向功能甚至shell从已知文件名重定向stdin

这里有一些例子。请注意,在每种情况下,
wc
都会报告 文件
input
的统计信息,而不是提供的生产者(其 是空的生产者。)


你在流什么?那是什么过程?总的来说,你想做什么?我修正了我的答案。没有什么比使用
sourceHandle
并自己关闭句柄更简单的了
ResourceT
很好,但它实际上只是一种方便。你在流什么?那是什么过程?总的来说,你想做什么?我修正了我的答案。没有什么比使用
sourceHandle
并自己关闭句柄更简单的了
ResourceT
很好,但这只是一种方便。嗨,谢谢你的回复。关于最初的答案,我想我没有明确提到它(我想它隐含在标题中),但我需要一整条管道,因为我需要处理输入和输出之间的数据。文件和过程只是开始和结束。关于您的更新,我已经说过,如果可能的话,我不希望使用sourceHandle,因为如果可能的话,我不希望处理我自己的文件打开和关闭。您的意思是,您希望在将输入文件传输到流程之前,通过另一个导管阶段发送输入文件的内容吗?您好,谢谢您的回复。关于最初的答案,我想我没有明确提到它(我想它隐含在标题中),但我需要一整条管道,因为我需要处理输入和输出之间的数据。文件和过程只是开始和结束。关于您的更新,我已经说过,如果可能的话,我不希望使用sourceHandle,因为如果可能的话,我不希望处理我自己的文件打开和关闭。您的意思是,您希望在将输入文件传输到流程之前,通过另一个导管阶段发送输入文件的内容吗?
#!/usr/bin/env stack
{- stack runghc --resolver lts-6.0
    --package conduit-extra
    --package conduit-combinators
 -}
{-# LANGUAGE OverloadedStrings #-}

import Conduit
import Data.Conduit
import Data.Conduit.Process
import qualified Data.ByteString.Char8 as BS

ex1 = do x <- sourceCmdWithConsumer "date" lengthC
         print x

emit prefix = mapM_C (\x -> BS.putStr prefix >> BS.putStr ": " >> BS.putStrLn x)

ex2 = do let cp = shell "wc < input"
         x <- sourceProcessWithConsumer cp (emit "stdout")
         print x

ex3 = sourceCmdWithStreams "wc < input" (return ())  (emit "stdout") (emit "stderr")

ex4 = do let cp = shell "wc < input"
         sourceProcessWithStreams cp (return ()) (emit "stdout") (emit "stderr" )
#!/usr/bin/env stack
{- stack runghc --resolver lts-6.0
    --package streaming-commons
    --package conduit
    --package conduit-extra
 -}

{-# LANGUAGE OverloadedStrings #-}

import System.IO
import qualified Data.ByteString.Char8 as BS
import Conduit
import System.Process
import Data.Conduit.Process

emit prefix = mapM_C $ \x -> BS.putStr prefix >> BS.putStr ": " >> BS.putStrLn x

ex3 = do let cp = (proc "wc" [])
         withFile "input" ReadMode $ \h -> do
           sourceProcessWithStreams cp (sourceHandle h) (emit "stdout") (emit "stderr")

main = ex3 >>= print