有些人可以帮我解决我的程序出了什么问题。当我试图运行以下程序时,我收到以下错误消息:
hSetFileSize
:无效参数(无效参数)
import System.IO
main = do
putStrLn "Enter file name (Including full path) to read"
fileName <- getLine
handle <- openFile fileName ReadMode
sizeBeforeTrunc <- hFileSize handle
content <- readFile fileName
putStrLn $ "Size of the file Before truncation is " ++ (show sizeBeforeTrunc) ++ " bytes"
putStrLn $ "Content of the file is " ++ content
putStrLn "**************************************"
let n = sizeBeforeTrunc `div` 2
putStrLn $ "Truncating file to " ++ (show n) ++ " bytes"
info1 <- hSetFileSize handle (toInteger 10)
putStrLn $ show info1
sizeAfterTrunc <- hFileSize handle
putStrLn $ "Size of the file After truncation is " ++ (show sizeAfterTrunc) ++ " bytes"
putStrLn $ "Content of the file is " ++ content
hClose handle
答案 0 :(得分:3)
您正在打开文件以供阅读;但截断是一种写操作。
你可以做的事情就像是
main = do
putStrLn "Enter file name (Including full path) to read"
fileName <- getLine
sizeBeforeTrunc <- withFile fileName ReadMode $ \h -> do
sizeBeforeTrunc <- hFileSize h
content <- hGetContents h
putStrLn $ "Size of the file Before truncation is " ++ (show sizeBeforeTrunc) ++ " bytes"
putStrLn $ "Content of the file is " ++ content
putStrLn "**************************************"
let n = sizeBeforeTrunc `div` 2
putStrLn $ "Truncating file to " ++ (show n) ++ " bytes"
sizeAfterTrunc <- withFile fileName WriteMode $ \h -> do
info1 <- hSetFileSize h (toInteger 10)
putStrLn $ show info1
hFileSize h
putStrLn $ "Size of the file After truncation is " ++ (show sizeAfterTrunc) ++ " bytes"
putStrLn $ "Content of the file is " ++ content
答案 1 :(得分:2)
注意:这个答案写在有文化的Haskell中。以> import System.IO
作为扩展名保存,并在GHCi中试用或编译。
readFile
更改文件不是只读操作。您需要打开文件进行编写。但是,这会导致问题,因为您可能只有一个作者或多个读者。由于您使用> putAndCount :: FileName -> String -> IO Int
> putAndCount fn msg = withFile fn ReadMode $ \handle -> do
> size <- hFileSize handle
> content <- hGetContents handle
> putStrLn $ "Size of the file " ++ msg ++ " is " ++ show size ++ " bytes"
> putStrLn $ "Content of the file is " ++ content
> return size
打开文件进行阅读,因此您无法简单地更改打开模式。
如果我们重构您的代码会变得更容易。我们可以立即看到两个不要自我重复的违规行为,即获取大小并告诉内容。所以,让我们解决一下:
withFile
> setFileSize :: FileName -> Integer -> IO ()
> setFileSize fn s = withFile fn ReadWriteMode $ \handle ->
> hSetFileSize handle s
确保我们的句柄已关闭,无法进一步操作。现在让我们编写另一个函数来改变文件的大小而不使用句柄:
ReadWriteMode
在此处使用WriteMode
和不 WriteMode
非常重要,因为fopen
会将文件截断为零字节!顺便说一句,这与C&#39 {s} > main :: IO ()
> main = do
> putStrLn "Enter file name (Including full path) to read"
> fileName <- getLine
>
> sizeBeforeTrunc <- putAndCount fileName "Before truncation"
> putStrLn "**************************************"
>
> let n = sizeBeforeTrunc `div` 2
> putStrLn $ "Truncating file to " ++ (show n) ++ " bytes"
> setFileSize fileName n
> putAndCount fileName "After truncation"
中的行为相同。
现在我们拥有完成任务所需的所有工具:
{{1}}