Tôi thấy mình đang làm nhiều hơn và nhiều kịch bản hơn trong haskell. Nhưng có một số trường hợp mà tôi thực sự không chắc chắn làm thế nào để làm điều đó "đúng".
ví dụ: sao chép một thư mục đệ quy (a la unix cp -r
).Cách haskell để sao chép một thư mục
Kể từ khi tôi chủ yếu sử dụng Linux và Mac Os Tôi thường gian lận:
import System.Cmd
import System.Exit
copyDir :: FilePath -> FilePath -> IO ExitCode
copyDir src dest = system $ "cp -r " ++ srC++ " " ++ dest
Nhưng cách khuyến khích để sao chép một thư mục một cách độc lập nền tảng là gì?
Tôi không tìm thấy bất kỳ điều gì phù hợp về tấn công.
Đây là thực hiện thay naiv của tôi, tôi sử dụng cho đến nay:
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
Mọi góp ý về những gì thực sự là cách để làm điều đó?
Tôi đã cập nhật điều này với các đề xuất của hammar và FUZxxl.
... nhưng tôi vẫn cảm thấy vụng về với tôi vì một nhiệm vụ phổ biến như vậy!
Nếu không có thư viện chuẩn như vậy tồn tại, tại sao không làm một? ;) –
Tôi nghĩ rằng điều này không xử lý các liên kết chính xác. Nó sẽ tái tạo chúng. Xem System.Posix.Files. – hasufell
Mã không hoạt động nếu src và dst không bị phân tách. 'copyDir" A "" A/B "' sẽ lặp vô hạn. Xem thêm https://github.com/yesodweb/Shelly.hs/issues/154 –