如何列出当前目录中的所有文件

时间:2011-07-11 11:22:36

标签: haskell file-io directory

我想要的是写一个Haskell函数来返回当前目录的文件,例如

将当前目录更改为

 :cd c:/code/haskell

然后编写一个函数,该函数返回集合中的文件,例如

 [x | x <-getDirectoryContents ]

编辑:

我写了一个像这样列出文件的函数  (参考:http://zvon.org/other/haskell/Outputdirectory/index.html

import Directory 

main = _dir "/tmp/FOO"

_dir _path =do
    setCurrentDirectory _path
    _cd <- getCurrentDirectory
    print _cd
    _file <- getDirectoryContents _cd
    print _file

所以调用_dir“c:/ code / haskell”将列出所有文件+目录名称(非递归)。我现在想要的是在谓词函数中调用它,例如:

[ x| x <- _dir  "c:/code/haskell" | x start with 'haskell_' ]  

所以我可以在文件名上应用过滤器

6 个答案:

答案 0 :(得分:20)

看来你正在寻找:

getDirectoryContents :: FilePath -> IO [FilePath]

参考:http://www.haskell.org/ghc/docs/6.12.2/html/libraries/directory-1.0.1.1/System-Directory.html#1

答案 1 :(得分:8)

以下内容如何:

import Data.List
import System.Directory

main = do all <- getDirectoryContents "/tmp/FOO"
          let filtered = filter (isPrefixOf "haskell") all
          print filtered

答案 2 :(得分:5)

第一点:表达式[x | x <- lst]lst完全相同,因此如果lst是一个列表,则无需使用列表推导。

第二:要[x | x <-getDirectoryContents ]工作,值getDirectoryContents应该是一个列表。但事实并非如此! getDirectoryContents是IO值。

您可以通过以下方式使用此功能(在monadic表达式中):

do 
  files <- getDirectoryContents "."
  print files

(或 - 在ghci中 - 使用:do; files <- getDirectoryContents "."; print files

files的类型为[FilePath],而while表达式的类型为IO ()

答案 3 :(得分:5)

编写一个返回当前目录中所有文件的函数所需要做的就是:

import System.Directory

filesInCurDir = getCurrentDirectory >>= getDirectoryContents

&gt;&gt; =运算符是值传递的monad排序运算符。这里最好的描述是http://www.haskell.org/tutorial/monads.html

如果你打算在ghci中使用这个:

let filesInCurDir = getCurrentDirectory >>= getDirectoryContents

您可以检查该函数是否为filesInCurDir :: IO [FilePath]类型,从而保持“monadic nature”。

因此,如果您想进一步过滤文件,您可以这样做:

let filteredFilesInCurDir = 
    getCurrentDirectory >>= 
    getDirectoryContents >>= 
    \files -> return [ x | x <- files, (length x) > 10 ]

如果您希望每次都通过过滤器:

let filterFilesInCurDir f = 
    getCurrentDirectory >>= 
    getDirectoryContents >>= 
    \files -> return [ x | x <- files, f x ]

与:

相同
let filteredFilesInCurDir f = 
    getCurrentDirectory >>= 
    getDirectoryContents >>= 
    return . filter f

你可以像以下一样使用它:

filterFilesInCurDir (\x -> (length x) > 2)

答案 4 :(得分:3)

filemanip套餐提供了一个 这个特定任务的功能更加通用和灵活。

即。列出给定目录中的常规文件

> :m + System.FilePath.Find
> :t find always (fileType ==? RegularFile)
find always (fileType ==? RegularFile) :: FilePath -> IO [FilePath]

此软件包与Windows兼容(因为它取决于unix-compat 只有unix)并且还有简洁的自我描述性的haddocs。

答案 5 :(得分:1)

这是使用Control.Applicative的另一种方法:

import Control.Applicative
import System.Directory

isRegularFileOrDirectory :: FilePath -> Bool
isRegularFileOrDirectory f = f /= "." && f /= ".."

main :: IO ()
main = do
  fileNames <- filter isRegularFileOrDirectory <$> getDirectoryContents "."
  putStrLn $ show $ fileNames