Comment detail

指定されたフォルダ以下のゴミ掃除 (Nested Flatten)

This comment is reply for 57 PHO: (指定されたフォルダ以下のゴミ掃除). Go to thread root.

setCurrentDirectory を使ってパスの扱いを単純化
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import System.Directory
import System.Environment

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

cleaning :: FilePath -> IO ()
cleaning = (>> removeBackupFiles) . setCurrentDirectory

removeBackupFiles :: IO ()
removeBackupFiles = getDirectoryContents "." >>= mapM_ rmbk . drop 2

rmbk :: FilePath -> IO ()
rmbk path
 = do { dir <- doesDirectoryExist path
      ; let backup = '~'== last path
      ; if dir 
           then if backup then removeDirectoryRecursive path else cleaning path
           else if backup then removeFile path               else return ()
      }
ごめんなさいバグがありました。
ディレクトリを降りていったあとにカレントディレクトリを
もとへ戻していなかった。こちらが正しいはずのコード
です。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import System.Directory
import System.Environment

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

cleaning :: FilePath -> IO ()
cleaning = (>> removeBackupFiles) . setCurrentDirectory

removeBackupFiles :: IO ()
removeBackupFiles
 = do { cwd <- getCurrentDirectory
      ; getDirectoryContents "." >>= mapM_ (rmbk cwd) . drop 2
      }

rmbk :: FilePath -> FilePath -> IO ()
rmbk cwd path
 = do { dir <- doesDirectoryExist path
      ; let backup = '~'== last path
      ; if dir 
           then if backup 
                   then removeDirectoryRecursive path 
                   else cleaning path >> setCurrentDirectory cwd
           else if backup 
                   then removeFile path
                   else return ()
      }
プログラム(修正版)にまだバグがあった.POSIX系のファイルシステムでは,
シンボリックリンクでディレクトリパスに循環があると停止しなくなってしまう.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
module Main (main) where

import System.Directory ( setCurrentDirectory, getCurrentDirectory
                        , getDirectoryContents
                        , removeDirectoryRecursive, removeFile )
import System.Posix.Files (getSymbolicLinkStatus, isDirectory)
import System.Environment (getArgs)

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

cleaning :: FilePath -> IO ()
cleaning = (>> removeBackupFiles) . setCurrentDirectory

removeBackupFiles :: IO ()
removeBackupFiles
 = do { cwd <- getCurrentDirectory
      ; getDirectoryContents "." >>= mapM_ (rmbk cwd) . drop 2
      }

rmbk :: FilePath -> FilePath -> IO ()
rmbk cwd path
 = do { fstat <- getSymbolicLinkStatus path
      ; let backup = '~'== last path
      ; if isDirectory fstat
           then if backup then removeDirectoryRecursive path 
                else cleaning path >> setCurrentDirectory cwd
           else if backup then removeFile path
                else return ()
      }

Index

Feed

Other

Link

Pathtraq

loading...