簡體   English   中英

慣用io-streams目錄遍歷

[英]Idiomatic io-streams directory traversal

我正在討論關於Reddit的一些代碼 ,這讓我對如何在io-streams中實現它感到好奇。 考慮以下代碼遍歷目錄結構並打印出所有文件名:

import           Control.Exception         (bracket)
import qualified Data.Foldable             as F
import           Data.Streaming.Filesystem (closeDirStream, openDirStream,
                                            readDirStream)
import           System.Environment        (getArgs)
import           System.FilePath           ((</>))

printFiles :: FilePath -> IO ()
printFiles dir = bracket
    (openDirStream dir)
    closeDirStream
    loop
  where
    loop ds = do
        mfp <- readDirStream ds
        F.forM_ mfp $ \fp' -> do
            let fp = dir </> fp'
            ftype <- getFileType fp
            case ftype of
                FTFile -> putStrLn fp
                FTFileSym -> putStrLn fp
                FTDirectory -> printFiles fp
                _ -> return ()
            loop ds

main :: IO ()
main = getArgs >>= mapM_ printFiles

而不是簡單地打印文件,假設我們想要創建某種流式文件路徑表示。 我知道這在枚舉器,管道和管道中是如何工作的。 但是,由於中間步驟需要獲取稀缺資源( DirStream ),我不確定io-stream的實現方式。 有人能舉例說明如何做到這一點嗎?

為了比較, 這里是管道實現 ,可以通過bracketPMonadResource 以下是管道代碼如何用於實現上述相同的文件打印程序:

import           Control.Monad.IO.Class       (liftIO)
import           Control.Monad.Trans.Resource (runResourceT)
import           Data.Conduit                 (($$))
import           Data.Conduit.Filesystem      (sourceDirectoryDeep)
import qualified Data.Conduit.List            as CL
import           System.Environment           (getArgs)

main :: IO ()
main =
    getArgs >>= runResourceT . mapM_ eachRoot
  where
    -- False means don't traverse dir symlinks
    eachRoot root = sourceDirectoryDeep False root
                 $$ CL.mapM_ (liftIO . putStrLn)

典型的風格是做這樣的事情:

traverseDirectory :: RawFilePath -> (InputStream RawFilePath -> IO a) -> IO a

即標准的“with-”功能,具有明顯的實現。

編輯 :添加了一個工作示例實現: https//gist.github.com/gregorycollins/00c51e7e33cf1f9c8cc0

它並不完全復雜,但它也不像我最初建議的那樣微不足道。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM