You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:33:49