0

I asked a question about "How to read a text file reversely with iterator in C#" sometime ago. Please see the link

Jon Skeet was very kind to provide a solution for me. But I still have a question how to close the data file when it is read? It seemed that Jon used a delegate to handle the iterator, which was very interesting. But How I can call something like "file.Close()" to release it when the file was processed?

Thanks,

Community
  • 1
  • 1
Liang Wu
  • 1,772
  • 3
  • 18
  • 26

3 Answers3

2

It was just a very regrettable oversight.

The answer is - as normal - to use try/finally or a using statement. That way the file will be closed even if an exception is thrown, and even if the caller doesn't iterate all the way back to the start of the file.

However, it does rely on the caller calling Dispose on the IEnumerator<T>. Fortunately that's handled automatically by a foreach loop in C#, but if you ever use GetEnumerator()/MoveNext()/Current explicitly, you should be careful and write code like this:

using (IEnumerator<string> iterator = foo.GetEnumerator())
{
    while (iterator.MoveNext())
    {
        string bar = iterator.Current;
        // etc
    }
}

Fortunately there aren't very many times when you need to do this :)

I've got more details as to how all of this works under the covers in my iterator implementation article which you may find useful.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0

Jon's code has a call to Dispose method when the file cannot be read further.
Is this what you are looking for?

Dispose will call Close & release the file handle.

shahkalpesh
  • 33,172
  • 3
  • 63
  • 88
  • Originally it only closed the stream if it wasn't seekable/readable. It now closes it using a try/finally block in the iterator part as well. – Jon Skeet Feb 24 '09 at 07:05
0

He called Dispose when it is a bad stream.

public IEnumerator<string> GetEnumerator()
    {
        Stream stream = streamSource();
        if (!stream.CanSeek)
        {
            stream.Dispose();
            throw new NotSupportedException("Unable to seek within stream");
        }
        if (!stream.CanRead)
        {
            stream.Dispose();
            throw new NotSupportedException("Unable to read within stream");
        }
        return GetEnumeratorImpl(stream);
    }

But when I do iteration, it does not seem to close the file. What I am trying to do after reading the file is to remove that file. But I got an exception saying it was used by another process.

Liang Wu
  • 1,772
  • 3
  • 18
  • 26