Unix目录操作


注:本文是用 literal haskell写成,直接可以编译本文。
近期同时在学习《Unix环境高级编程》与Haskell语言,正好结合起来。
第一章中的例子,列出目录中的文件,以及获得当前目录名:

> import System.IO

System.Posix 库中包含了Posix函数,Unix下的大部分操作在这里

> import System.Posix

System.Directory 中包含了很多目录操作的函数,比直接用 Posix 方便

> import System.Directory

显式当前工作目录

> show_current_dir :: IO ()
> show_current_dir = do
>   curr_dir <- getWorkingDirectory
>   putStrLn ("Current Working Directory:" ++ curr_dir)

列出一个目录中的文件列表,可以使用 System.Directory 比较方便,也可以使用 Posix 函数
这里使用 System.Directory 中的 getDirectoryContents 函数:
getDirectoryContents :: FilePath -> IO[FilePath]

Seeing as you're not doing anything with the results of this map, you
probably want to use mapM_ instead. Then the result type of ls_dir1
can be IO (), which is neater.  -- by David House from Haskell-Cafe

> ls_dir1 :: String -> IO ()
> ls_dir1 fp = do
>   files <- getDirectoryContents fp
>   putStrLn ("ls_dir1: Files in " ++ fp ++ ":")
>   mapM_ putStrLn files

在C语言中,使用循环来读取一个目录中的文件列表:
dp = opendir("/");
while ((dirp = readdir(dp)) != NULL)
  printf("%s\n", dirp->d_name);
  
closedir(dp);
对应到Haskell程序中,通过递归读取所有的文件名:

> read_fp_from_DirStream :: DirStream -> IO()
> read_fp_from_DirStream dp = do
>   f <- readDirStream dp
>   if f == "" then return () else do putStrLn f
>                                     read_fp_from_DirStream dp
>               
> ls_dir2 :: String -> IO ()
> ls_dir2 fp = do
>   dp <- openDirStream fp
>   putStrLn ("ls_dir2: files in " ++ fp ++ ":")
>   read_fp_from_DirStream dp
>   closeDirStream dp

主函数

> main :: IO ()
> main = do
>   putStrLn "Unix programming use Haskell"
>   show_current_dir
>   ls_dir1 "/"
>   ls_dir2 "/home"