Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
62
Task/Find-duplicate-files/Haskell/find-duplicate-files.hs
Normal file
62
Task/Find-duplicate-files/Haskell/find-duplicate-files.hs
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import Crypto.Hash.MD5 (hash)
|
||||
import Data.ByteString as BS (readFile, ByteString())
|
||||
import System.Environment (getArgs, getProgName)
|
||||
import System.Directory (doesDirectoryExist, getDirectoryContents)
|
||||
import System.FilePath.Posix ((</>))
|
||||
import Control.Monad (forM)
|
||||
import Text.Printf (printf)
|
||||
import System.IO (withFile, IOMode(ReadMode), hFileSize)
|
||||
|
||||
|
||||
type File = (BS.ByteString, -- md5hash
|
||||
FilePath) -- filepath
|
||||
|
||||
type FileSize = Integer
|
||||
|
||||
getRecursiveContents :: FilePath -> FileSize -> IO [File]
|
||||
getRecursiveContents curDir maxsize = do
|
||||
names <- getDirectoryContents curDir
|
||||
let dirs = filter (`notElem` [".", ".."]) names
|
||||
files <- forM dirs $ \path -> do
|
||||
let path' = curDir </> path
|
||||
exists <- doesDirectoryExist path'
|
||||
if exists
|
||||
then getRecursiveContents path' maxsize
|
||||
else genFileHash path' maxsize
|
||||
return $ concat files
|
||||
|
||||
|
||||
genFileHash :: FilePath -> FileSize -> IO [File]
|
||||
genFileHash path maxsize = do
|
||||
size <- withFile path ReadMode hFileSize
|
||||
if size <= maxsize
|
||||
then BS.readFile path >>= \bs -> return [(hash bs, path)]
|
||||
else return []
|
||||
|
||||
findDuplicates :: FilePath -> FileSize -> IO ()
|
||||
findDuplicates dir bytes = do
|
||||
exists <- doesDirectoryExist dir
|
||||
if exists
|
||||
then getRecursiveContents dir bytes >>= findSameHashes
|
||||
else printf "Sorry, the directory \"%s\" does not exist...\n" dir
|
||||
|
||||
findSameHashes :: [File] -> IO ()
|
||||
findSameHashes [] = return ()
|
||||
findSameHashes ((hash, fp):xs) = do
|
||||
case lookup hash xs of
|
||||
(Just dupFile) -> printf "===========================\n\
|
||||
\Found duplicate:\n\
|
||||
\=> %s \n\
|
||||
\=> %s \n\n" fp dupFile
|
||||
>> findSameHashes xs
|
||||
(_) -> findSameHashes xs
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
args <- getArgs
|
||||
case args of
|
||||
[dir, mbytes] | [(bytes ,"")] <- reads mbytes
|
||||
, bytes >= 1 -> findDuplicates dir bytes
|
||||
(_) -> do
|
||||
name <- getProgName
|
||||
printf "Something went wrong - please use ./%s <dir> <bytes>\n" name
|
||||
Loading…
Add table
Add a link
Reference in a new issue