sách gpt4 ai đã đi

haskell pipes - nhiều tệp đầu ra trong một pipe

In lại 作者:行者123 更新时间:2023-12-04 05:50:23 31 4
mua khóa gpt4 Nike

我正在编写一个程序,其中输入文件被拆分为多个文件(Shamir 的 secret 共享方案)。

这是我想象的管道:

  • nguồn:使用 Conduit.Binary.sourceFile 从输入中读取
  • 导管:获取一个 ByteString,产生 [ByteString]
  • 水槽:从管道中获取 [ByteString],并将每个 ByteString(在 [ByteString] 中)写入其相应的文件。 (假设我们的输入 [ByteString] 被称为 bsl,那么 bsl !! 0 将被写入文件 0,bsl !! 1 被写入文件 1 等等)

  • 我发现了一个关于多个输入文件的问题 đây ,但在他们的情况下,整个管道为每个输入文件运行一次,而对于我的程序,我正在写入管道中的多个输出文件。

    我也在查看 Conduit 源代码 đây看看我是否可以自己实现一个 multiSinkFile,但是我对 sinkFile 的 Consumer 类型有点困惑,如果我尝试更深入地挖掘,更是如此......(我还是个初学者)

    所以,问题是,我应该如何实现像 multiSinkFile 这样的函数,它允许将多个文件作为接收器的一部分写入?

    任何提示表示赞赏!

    澄清

    假设我们要对包含二进制值“ABCDEF”(分为 3 部分)的文件进行 Shamir 的 secret 共享。

    (所以我们有我们的输入文件 srcFile 和我们的输出文件 outFile0 , outFile1outFile2 )

    我们首先从文件中读取“ABC”,然后进行处理,这将为我们提供一个列表,例如 ["133", "426", "765"]。 .所以 "133"将写入 outFile0 , "426"ĐẾN outFile1"765"ĐẾN outFile2 .然后我们从 srcFile 中读取“DEF” ,对其进行处理,并将相应的输出写入每个输出文件。

    biên tập:

    谢谢您的回答。我花了一些时间来了解 ZipSinks 等的情况,并且我编写了一个简单的测试程序,它接受源文件的输入并将其简单地写入 3 个输出文件。希望这将在 future 对其他人有所帮助。
    {-# LANGUAGE NoImplicitPrelude #-}
    {-# LANGUAGE RankNTypes #-}
    {-# LANGUAGE OverloadedStrings #-}
    import ClassyPrelude.Conduit
    import Safe (atMay)
    import Text.Printf
    import Filesystem.Path.CurrentOS (decodeString, encodeString)
    import Control.Monad.Trans.Resource (runResourceT, ResourceT(..))

    -- get the output file name given the base (file) path and the split number
    getFileName :: FilePath -> Int -> FilePath
    getFileName basePath splitNumber = decodeString $ encodeString basePath ++ "." ++ printf "%03d" splitNumber

    -- Get the sink file, given a filepath generator (that takes an Int) and the split number
    idxSinkFile :: MonadResource m
    => (Int -> FilePath)
    -> Int
    -> Consumer [ByteString] m ()
    idxSinkFile mkFP splitNumber =
    concatMapC (flip atMay splitNumber) =$= sinkFile (mkFP splitNumber)

    sinkMultiFiles :: MonadResource m
    => (Int -> FilePath)
    -> [Int]
    -> Sink [ByteString] m ()
    sinkMultiFiles mkFP splitNumbers = getZipSink $ otraverse_ (ZipSink . idxSinkFile mkFP) splitNumbers

    simpleConduit :: Int -> Conduit ByteString (ResourceT IO) [ByteString]
    simpleConduit num = mapC (replicate num)

    main :: IO ()
    main = do
    let mkFP = getFileName "test.txt"
    splitNumbers = [0..2]
    runResourceT $ sourceFile "test.txt" $$ simpleConduit (length splitNumbers) =$ sinkMultiFiles mkFP splitNumbers

    1 Câu trả lời

    一种可能性是让您的算法输出类似于 (Int, ByteString) 的内容。 , 其中 Int是指定输出文件的索引(当然您可以使用任何其他类型作为键)。这样,管道可以决定它想要将其输出附加到哪个文件。

    import Data.Conduit
    import qualified Data.Conduit.List as C
    import qualified Data.Foldable as F

    -- | Filter only pairs tagged with the appropriate key.
    filterInputC :: (Monad m, Eq k) => k -> Conduit (k, a) m a
    filterInputC idx = C.filter ((idx ==) . fst) =$= C.map snd

    -- | Prepend a given sink with a filter.
    filterInput :: (Monad m, Eq k) => k -> Sink a m r -> Sink (k, a) m r
    filterInput idx = (filterInputC idx =$)

    -- | Given a list of sinks, create a single sink that directs received values
    -- depending on the index.
    multiSink_ :: (Monad m) => [Sink a m ()] -> Sink (Int, a) m ()
    multiSink_ = getZipSink . F.sequenceA_ . fmap ZipSink
    . zipWith filterInput [0..]

    làm mới:以下示例显示了 multiSink_可以使用(测试接收器只是将所有内容打印到带有适当前缀的标准输出,而不是写入文件)。
    -- | A testing sink that just prints its input, marking it with
    -- a given prefix.
    testSink :: String -> Sink String IO ()
    testSink prefix = C.mapM_ (putStrLn . (prefix ++))

    -- | An example that produces indexed output.
    testSource :: (Monad m) => Source m (Int, String)
    testSource = do
    yield (0, "abc")
    yield (0, "def")
    yield (1, "opq")
    yield (0, "0")
    yield (1, "1")
    yield (2, "rest")

    main :: IO ()
    main = testSource $$ multiSink_ (map testSink ["1: ", "2: ", "3: "])

    关于haskell - 管道 - 管道内的多个输出文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23169458/

    31 4 0
    行者123
    Hồ sơ cá nhân

    Tôi là một lập trình viên xuất sắc, rất giỏi!

    Nhận phiếu giảm giá Didi Taxi miễn phí
    Mã giảm giá Didi Taxi
    Giấy chứng nhận ICP Bắc Kinh số 000000
    Hợp tác quảng cáo: 1813099741@qq.com 6ren.com