Thanks Ryan, this will definitely not leak handles. I had thought about making a strict version of hGetContents, though on a bit different lines.<br><br>My question was that since the documentation says that the semi-closed handle becomes closed as soon as the entire contents have been read; can I conclude that as far as I consume the string, I am not leaking handles?<br>
<br>I am still interested in using hGetContents, since these contents are going soon through hPutStr, which will consume it anyway. And hGetContents being lazy will not occupy memory of the order of size of the input file. That&#39;s why the question.<br>
<br>Regards,<br>Abhay<br><br><div class="gmail_quote">On Tue, Apr 15, 2008 at 1:07 PM, Ryan Ingram &lt;<a href="mailto:ryani.spam@gmail.com">ryani.spam@gmail.com</a>&gt; wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
I usually use something like this instead:<br>
<br>
hStrictGetContents :: Handle -&gt; IO String<br>
hStrictGetContents h = do<br>
 &nbsp; &nbsp;s &lt;- hGetContents h<br>
 &nbsp; &nbsp;length s `seq` hClose h<br>
 &nbsp; &nbsp;return s<br>
<br>
This guarantees the following:<br>
1) The whole file is read before hStrictGetContents exits (could be<br>
considered bad, but usually it&#39;s The Right Thing)<br>
2) You guarantee that you don&#39;t leak file handles (good benefit!)<br>
<br>
A slightly better version:<br>
<br>
import qualified Data.ByteString.Char8 as B<br>
<br>
hStrictGetContents :: Handle -&gt; IO String<br>
hStrictGetContents h = do<br>
 &nbsp; &nbsp;bs &lt;- B.hGetContents h<br>
 &nbsp; &nbsp;hClose h -- not sure if this is required; ByteString documentation<br>
isn&#39;t clear.<br>
 &nbsp; &nbsp;return $ B.unpack bs -- lazy unpack into String<br>
<br>
This saves a ton of memory for big reads; a String is ~12 bytes per<br>
character, this is only 1 byte per character + fixed overhead. &nbsp;Then,<br>
assuming the function consuming the String doesn&#39;t leak, you&#39;ll end up<br>
with a much smaller space requirement.<br>
<br>
 &nbsp;-- ryan<br>
<div><div></div><div class="Wj3C7c"><br>
2008/4/14 Abhay Parvate &lt;<a href="mailto:abhay.parvate@gmail.com">abhay.parvate@gmail.com</a>&gt;:<br>
&gt; Thanks! I was worried about how/where would I place hClose!<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; On Mon, Apr 14, 2008 at 10:58 PM, Brent Yorgey &lt;<a href="mailto:byorgey@gmail.com">byorgey@gmail.com</a>&gt; wrote:<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; 2008/4/14 Abhay Parvate &lt;<a href="mailto:abhay.parvate@gmail.com">abhay.parvate@gmail.com</a>&gt;:<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; &gt; Hello,<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; In describing the Handle type, the GHC documentation says (in the<br>
&gt; System.IO documentation):<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; GHC note: a Handle will be automatically closed when the garbage<br>
&gt; collector detects that it has become unreferenced by the program. However,<br>
&gt; relying on this behaviour is not generally recommended: the garbage<br>
&gt; collector is unpredictable. If possible, use explicit an explicit hClose to<br>
&gt; close Handles when they are no longer required. GHC does not currently<br>
&gt; attempt to free up file descriptors when they have run out, it is your<br>
&gt; responsibility to ensure that this doesn&#39;t happen.<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; But one cannot call hClose on Handles on which something like<br>
&gt; hGetContents has been called; it just terminates the character list at the<br>
&gt; point till which it has already read. Further the manual says that<br>
&gt; hGetContents puts the handle in the semi-closed state, and further,<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; A semi-closed handle becomes closed:<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; if hClose is applied to it;<br>
&gt; &gt; &gt; if an I/O error occurs when reading an item from the handle;<br>
&gt; &gt; &gt; or once the entire contents of the handle has been read. So do I safely<br>
&gt; assume here, according to the third point above, that it&#39;s fine if I do not<br>
&gt; call hClose explicitly as far as I am consuming all the contents returned by<br>
&gt; hGetContents?<br>
&gt; &gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; Yes, not only is it fine, it&#39;s recommended! &nbsp;Calling hClose explicitly on<br>
&gt; a handle after calling hGetContents is a sure way to introduce bugs.<br>
&gt; &gt;<br>
&gt; &gt; -Brent<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt;<br>
&gt;<br>
</div></div>&gt; _______________________________________________<br>
&gt; &nbsp;Haskell-Cafe mailing list<br>
&gt; &nbsp;<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
&gt; &nbsp;<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
&gt;<br>
&gt;<br>
</blockquote></div><br>