为何getFileSize无法从System.Directory模块导入?
解决Haskell中
getFileSize导入错误及代码逻辑问题 嘿,我来帮你拆解这个问题,其实有两个关键点需要注意:
1. 导入错误的核心原因:版本兼容性问题
你遇到的Module ‘System.Directory’ does not export ‘getFileSize’错误,是因为getFileSize这个函数是在directory包的1.3.0.0版本才新增的。如果你的开发环境中安装的directory包版本低于这个版本,编译器就会认为这个函数不存在。
你可以通过以下命令查看当前使用的directory包版本:
- 如果你用cabal:
cabal info directory - 如果你用stack:
stack ls dependencies
2. 代码里的逻辑错误(即使导入成功也会报错)
就算你升级了包解决了导入问题,你的代码还是会出错——因为getFileSize的参数是FilePath(文件路径字符串),而你代码里的ff是openFile返回的Handle(已打开的文件句柄),类型不匹配,根本无法直接传入。
而且原代码还有个小问题:当文件大小为0时,你没有关闭打开的文件句柄,会造成资源泄漏。
修正方案
方案一:升级directory包到1.3.0.0及以上
- 用cabal升级:
cabal update && cabal install directory --constraint='directory >=1.3.0.0' - 用stack升级:修改你的
stack.yaml,将resolver切换到包含1.3.0.0+版本directory的,比如lts-10.0及以上版本的resolver。
方案二:不升级包,用更适合当前场景的函数
既然你已经打开了文件句柄,直接用System.IO里的hFileSize来获取文件大小会更合理,这个函数接受Handle作为参数,而且不需要依赖高版本的directory包。修正后的代码如下:
import System.Directory (getDirectoryContents, doesFileExist) import System.IO (openFile, hGetLine, hClose, IOMode(ReadMode), hFileSize) readALine :: FilePath -> IO () readALine fname = do print $ "Filename: " ++ fname ff <- openFile fname ReadMode size <- hFileSize ff if size > 0 then do fline <- hGetLine ff hClose ff print $ "First line: " <> fline else do hClose ff return ()
这个版本不仅解决了导入问题,还修复了资源泄漏的隐患,逻辑也更通顺。
内容的提问来源于stack exchange,提问作者rnso
相关产品推荐
相关产品推荐

