You're running into the usual hurdles of lazy IO... lazy IO sounds like an excellent idea, making streaming a snap until you start getting those awful problems.
Not that your particular case wouldn't be a red herring to an experienced Haskeller : this is the textbook example of why lazy IO is a problem.
main = do xs <- withFile "test.txt" ReadMode getlines
sequence_ $ map putStrLn xs
withFile takes a FilePath, a mode and an action to do with the handle resulting from opening this filepath with this mode. The interesting part from withFile is that it is implemented with bracket and guarantee, even in case of exception, than the file will be closed after the action on the handle executes. The problem here is that the action in question (getLines) don't read the file at all ! It only promise to do so when the content is really needed ! This is lazy IO (implemented with the unsafeInterleaveIO, guess what the "unsafe" part means...). Of course by the time this content is needed (putStrLn), the handle was closed by withFile as promised.
So you have several solutions : You could use open and close explicitly (and relinquish exception-safety), or you could use lazy IO but put every action touching the file content in the scope protected by withFile :
main = withFile "test.txt" ReadMode$ \h -> do
xs <- getlines h
mapM_ putStrLn xs
In this case, this is not too awful, but you should see that the problem may become more annoying, if you ignore when the content will be needed. Lazy IO in a big and complex program may fast become pretty annoying, and when further limitation on opened handle numbers starts to matter... Which is why the new sport of the Haskell community is to come up with solutions to the problem of streaming content (instead of reading the whole files in memory which "solve" the problem at the cost of bloating memory use to sometimes impossible levels) without lazy IO. For a time it seemed as if Iteratee was going to become the standard solution, but it was very complex and hard to understand, even for experienced Haskeller, so other candidates have crept up lately : the most promising or at least successful at present seems to be "conduit".