簡體   English   中英

什么是haskell復制目錄的方法

[英]What is the haskell way to copy a directory

我發現自己在haskell中做了越來越多的腳本。 但在某些情況下,我真的不確定如何“正確”地做到這一點。
例如,遞歸地復制目錄(la unix cp -r )。

由於我主要使用Linux和Mac Os,我通常作弊:

import System.Cmd
import System.Exit

copyDir ::  FilePath -> FilePath -> IO ExitCode
copyDir src dest = system $ "cp -r " ++ src ++ " " ++ dest

但是,以獨立於平台的方式復制目錄的推薦方法是什么?
我沒有找到任何適合hackage的東西。

這是我到目前為止使用的相當天真的實現:

import System.Directory
import System.FilePath((</>))
import Control.Applicative((<$>))
import Control.Exception(throw)
import Control.Monad(when,forM_)

copyDir ::  FilePath -> FilePath -> IO ()
copyDir src dst = do
  whenM (not <$> doesDirectoryExist src) $
    throw (userError "source does not exist")
  whenM (doesFileOrDirectoryExist dst) $
    throw (userError "destination already exists")

  createDirectory dst
  content <- getDirectoryContents src
  let xs = filter (`notElem` [".", ".."]) content
  forM_ xs $ \name -> do
    let srcPath = src </> name
    let dstPath = dst </> name
    isDirectory <- doesDirectoryExist srcPath
    if isDirectory
      then copyDir srcPath dstPath
      else copyFile srcPath dstPath

  where
    doesFileOrDirectoryExist x = orM [doesDirectoryExist x, doesFileExist x]
    orM xs = or <$> sequence xs
    whenM s r = s >>= flip when r

有什么方法可以做到這一點嗎?


我用hammar和FUZxxl的建議更新了這個。
......但是對於這樣一個共同的任務,我仍然感覺有些笨拙!

可以使用Shelly庫來執行此操作,請參閱cp_r

cp_r "sourcedir" "targetdir"

Shelly首先嘗試使用本機cp -r如果可用)。 如果沒有,它將回退到本機Haskell IO實現。

有關cp_r類型語義的更多詳細信息,請參閱我撰寫的這篇文章 ,描述如何將cp_rStringText

Shelly不依賴於平台,因為它依賴於Unix軟件包,Windows不支持。

我在Hackage上找不到任何可以做到這一點的東西。

你的代碼看起來對我很好。 一些評論:

  1.  dstExists <- doesDirectoryExist dst 

    這不考慮具有目標名稱的文件可能存在。

  2.  if or [not srcExists, dstExists] then print "cannot copy" 

    您可能希望拋出異常或返回狀態,而不是直接從此函數打印。

  3.  paths <- forM xs $ \\name -> do [...] return () 

    由於您沒有使用任何paths ,您可以將其更改為

     forM_ xs $ \\name -> do [...] 

filesystem-trees包提供了一種非常簡單的實現方法:

import System.File.Tree (getDirectory, copyTo_)

copyDirectory :: FilePath -> FilePath -> IO ()
copyDirectory source target = getDirectory source >>= copyTo_ target

我假設Path.IO copyDirRecur中的函數包含/排除符號鏈接的變體可能是一個更新且維護的解決方案。 它需要將文件路徑轉換為Path x Dir ,這是使用parseRelDir相應的parseAbsDir實現的,但我認為有一個比FilePath更精確的日期類型值得,以避免在運行時難以跟蹤錯誤。

MissingH包提供遞歸目錄遍歷,您可以使用它來簡化代碼。

還有一些函數用於復制核心Haskell庫Cabal模塊中的文件和目錄,特別是包Cabal中的Distribution.Simple.Utils。 copyDirectoryRecursive是一個,在該模塊中有一個附近的其他函數。

暫無
暫無

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

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