

Hi Tom,


Attached is a haskell file I wrote when I was learning how to use the

directory functions. It builds a tree structure corresponding to the
directory

tree and finds the files that end in ".txt". It then sorted the files
in order

of modification time. As you can guess from the program, it was for
managing

weblog entries in Blosxom.


It's beginner-ish code, but you can probably adapt it to your needs.

Note that the top level directory name "dir" is hardcoded into the
program.



Best Wishes,

Greg



On Jun 22, 2004, at 5:20 AM, Tom Hofte wrote:


<excerpt><fontfamily><param>Arial</param><smaller>Hi,</smaller></fontfamily>

 

<fontfamily><param>Arial</param><smaller>I'm looking for a way to
iteratively read all the files in a directory and</smaller></fontfamily>

<fontfamily><param>Arial</param><smaller>its subdirectories, given the
filepath of the top-level dir.</smaller></fontfamily>

<fontfamily><param>Arial</param><smaller>For example, I want to find a
file, corresponding to a given filename, in a directory and its
subdirectories.</smaller></fontfamily>

 

<fontfamily><param>Arial</param><smaller>Is there a way to implement
this in Haskell?</smaller></fontfamily>

 

<fontfamily><param>Arial</param><smaller>Kind regards,</smaller></fontfamily>

 

<fontfamily><param>Arial</param><smaller>Tom Hofte</smaller></fontfamily>

 

_______________________________________________

Haskell mailing list

Haskell@haskell.org

http://www.haskell.org/mailman/listinfo/haskell


</excerpt>

dirtree.hs:


--

-- walk a directory tree and find all of the files ending in .txt

--


module Main (main) where


import Monad

import Directory

import Text.Regex

import List


--

-- dirTree returns a tree with nodes containing file

-- information or directory information and a subdirectory.

--


data DTree = FileNode String | DirNode String [DTree]



addPrefix d str = do return (d ++ str)

addSuffix d str = do return (str ++ d)


scanDir d = do

        dentries <<- getDirectoryContents d


        files  <<- mapM (addPrefix d) dentries

        ffiles <<- filterM doesFileExist files


        -- directory names require extra processing: we must delete
the "." and ".." entries

        -- and add a trailing "/"


        dirs    <<- filterM (\x -> do return (x /= "." && x /= ".."))
dentries

        ddirs   <<- mapM (addPrefix d) dirs

        dddirs  <<- mapM (addSuffix "/") ddirs

        subdirs <<- filterM doesDirectoryExist dddirs


        subDTrees <<- mapM scanDir subdirs


        return (DirNode d ((map (\f -> FileNode f) ffiles) ++
subDTrees))



-- walk a directory tree, printing the contents


showDTree (FileNode fname) = do print fname

showDTree (DirNode  dname ds) = do

        print dname

        mapM showDTree ds

        return ()


-- given a directory tree, find the files that end in ".txt"


findTxt (DirNode dname ds) = concat (map findTxt ds)

findTxt (FileNode fname)   = if (isTextFile fname) then [fname] else []


-- given a file name, see if it ends in ".txt"


isTextFile f = (matchRegex regexp f) /= Nothing where regexp = mkRegex
".*txt"

printIfMatched f = if (isTextFile f) then do print f else do return ()



dir = "/Users/gwright/Desktop/Blosxom/docs/"


timeSortedFiles d = do

       directoryTree <<- scanDir d

       showDTree directoryTree

       textFiles     <<- do return (findTxt directoryTree)

       modTimes      <<- mapM getModificationTime textFiles


       fs  <<- do return (sortBy (\(f1,t1) (f2,t2) -> compare t1 t2)
(zip textFiles modTimes))

       return (map fst fs)



main = do

       fs  <<- timeSortedFiles dir

       fs' <<- do return (take 1 fs)

       mapM (\f -> do c <<- readFile f; putStr c) fs'

       return ()

 

