Search code examples
c#xmlprogress-barlarge-files

XmlReader - How to update progress bar


I'm reading really large XML files (more than 6GB of data) using XmlReader to speedup everything and works really well.

I'm doing this operation in another thread, (not with Background Worker) and I can't figure out how to update the progress bar, because XmlReader doesn't haves some sort of "current position, consumed bytes" or something like that who can help me to create an average calculation about the progress.

I tried to use XmlReader along with StreamReader to can count the bytes of every line, and after that updating the progress bar based on the consumed bytes / the file length * 100, but the program at some point give me an error like

Name cannot begin with the '<' character, hexadecimal value 0x3C. Line 109, position 27.'

when using the StreamReader Encoding.UTF8.GetByteCount(ReadLine()).

What is a good method to achieve this? I've searched on google and found some ways to achieve this, but without using XmlReader, and I can't not use XmlReader.

Thank you!


Solution

  • You could look at the position of the underlying stream:

    using (var fileStream = File.OpenRead("somePath"))
    {
        using (var reader = XmlReader.Create(fileStream))
        {
            long lastPosition = 0;
    
            while (reader.Read())
            {
                if (lastPosition != fileStream.Position)
                {
                    lastPosition = fileStream.Position;
    
                    Console.WriteLine($"Read {lastPosition} from {fileStream.Length} ({100.0 * lastPosition / fileStream.Length}%)");
                }
            }
        }
    }
    

    Notice that this will give you different outputs depending on the underlying stream that you use. On my system, the reader reads blocks of 4KB.