无法写入句柄
Can't write to a Handle
我正在 Haskell 中编写一个聊天服务器。我的可执行文件具有以下代码:
data Client = Client {idx :: Int, hClient :: Handle} deriving (Show, Eq)
tellClient :: String -> Client -> IO ()
tellClient = flip $ hPutStrLn . hClient
askClient :: Client -> IO (String)
askClient = hGetLine . hClient
我希望能够用来写入和读取文件。我正在使用 HSpec 针对此代码编写测试。我有以下功能来构建临时 Client
对象(依赖于 "temporary")库:
withTempClient :: Int -> (Client -> IO a) -> IO a
withTempClient cIdx f = withTempFile "tests/generated" "clientFile.tmp" axn
where axn _ handle = f $ Client cIdx handle
我正在使用它来测试上面的代码,如下所示:
main = hspec $ do
describe "client IO" $ do
it "can ask and tell" $ withTempClient 1 $ \c -> do
tellClient "hello" c
hFlush $ hClient c
askClient c `shouldReturn` "hello"
但是测试失败并出现以下错误:
uncaught exception: IOException of type EOF (test/generated
/clientFile11587.tmp: hGetLine: end of file)
我想也许我在withTempClient
中做错了什么,所以我添加了以下测试用例:
it "opens a handle corectly" $ withTempClient 1 $ \(Client _ h) -> do
hIsOpen h `shouldReturn` True
hIsWritable h `shouldReturn` True
但是已经过去了,所以我不确定问题出在哪里。我错过了什么?
当您写入文件时,OS 会跟踪您在该文件中的位置。你得到一个 EOF
错误,因为你在文件的末尾(开始时它是空的,你写的所有内容都在 之前 当前位置)。
要解决这个问题,您需要使用 hSeek
将自己重新定位在文件的开头,如下所示:
hSeek (hClient c) AbsoluteSeek 0
更多求索细节,参见。这点 real world haskell.
我正在 Haskell 中编写一个聊天服务器。我的可执行文件具有以下代码:
data Client = Client {idx :: Int, hClient :: Handle} deriving (Show, Eq)
tellClient :: String -> Client -> IO ()
tellClient = flip $ hPutStrLn . hClient
askClient :: Client -> IO (String)
askClient = hGetLine . hClient
我希望能够用来写入和读取文件。我正在使用 HSpec 针对此代码编写测试。我有以下功能来构建临时 Client
对象(依赖于 "temporary")库:
withTempClient :: Int -> (Client -> IO a) -> IO a
withTempClient cIdx f = withTempFile "tests/generated" "clientFile.tmp" axn
where axn _ handle = f $ Client cIdx handle
我正在使用它来测试上面的代码,如下所示:
main = hspec $ do
describe "client IO" $ do
it "can ask and tell" $ withTempClient 1 $ \c -> do
tellClient "hello" c
hFlush $ hClient c
askClient c `shouldReturn` "hello"
但是测试失败并出现以下错误:
uncaught exception: IOException of type EOF (test/generated
/clientFile11587.tmp: hGetLine: end of file)
我想也许我在withTempClient
中做错了什么,所以我添加了以下测试用例:
it "opens a handle corectly" $ withTempClient 1 $ \(Client _ h) -> do
hIsOpen h `shouldReturn` True
hIsWritable h `shouldReturn` True
但是已经过去了,所以我不确定问题出在哪里。我错过了什么?
当您写入文件时,OS 会跟踪您在该文件中的位置。你得到一个 EOF
错误,因为你在文件的末尾(开始时它是空的,你写的所有内容都在 之前 当前位置)。
要解决这个问题,您需要使用 hSeek
将自己重新定位在文件的开头,如下所示:
hSeek (hClient c) AbsoluteSeek 0
更多求索细节,参见。这点 real world haskell.