【问题标题】:get file content if file exists or default String如果文件存在或默认字符串,则获取文件内容
【发布时间】:2018-08-07 14:24:39
【问题描述】:

我检查了doesFileExist filePath 但是 我如何仅在文件存在时使用handle <- openFile filePath ReadMode

或者当文件不存在时如何获取默认字符串?

getFileContent filePath = do
    handle <- openFile filePath ReadMode
    content <- hGetContents handle
    return content

main = do
    blacklistExists <- doesFileExist "./blacklist.txt"
    let fileContent = if not blacklistExists
            then ""
            else getFileContent "./blacklist.txt"

    putStrLn fileContent

【问题讨论】:

    标签: haskell io


    【解决方案1】:

    像这样:

    import Control.Exception
    
    getFileContentOrElse :: String -> FilePath -> IO String
    getFileContentOrElse def filePath = readFile filePath `catch`
        \e -> const (return def) (e :: IOException)
    
    main = getFileContentOrElse "" "blacklist.txt" >>= putStrLn
    

    const _ (e :: IOException) 位只是为了能够给e 一个类型注释,以便catch 知道要使用哪个Exception 实例。

    【讨论】:

      【解决方案2】:

      我们可以如下解决编译错误。问题是getFileContentIO String"" 只是String。我们可以使用return :: Monad m =&gt; a -&gt; m a 将数据包装成例如IO

      那我们还需要“将IO String携带的数据在我们要打印的时候解包,所以我们可以把main改成:

      main = do
          blacklistExists <- doesFileExist "./blacklist.txt"
          fileContent <- if not blacklistExists
                  then return ""
                  else getFileContent "./blacklist.txt"
          putStrLn fileContent

      话虽如此,上述内容并不是很“安全”。例如,可能在检查存在和打开文件之间,有人删除了文件。也有可能是文件存在,但无法读取等。

      因此,使用“E更容易Ask FP授权更好( EAFP)" 方法,我们的目标是打开文件,如果出现问题,我们返回空字符串,就像 @DanielWagner 建议的那样。

      【讨论】:

        猜你喜欢
        • 2018-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-09
        • 2015-07-15
        • 2023-03-16
        • 1970-01-01
        • 2022-06-23
        相关资源
        最近更新 更多