遵循巨大的XML文件加载进度进度、加载、巨大、文件

2023-09-04 10:35:03 作者:暖色调

我尽量遵循大的XML文件的加载进度(我不是这些文件的提供者)的DOTNET(C#,框架3.5 SP1):从1 MB到300 MB通过网络文件共享

I try to follow the loading progress of big XML files (I'm not the provider of these files) in dotnet (C#, framework 3.5 SP1) : from 1 MB to 300 MB over a network file share.

我用一个XmlReader加载的目的,而不是直接XMLDocument.load方法方法加快加载过程。

I use an XmlReader for loading purpose instead of direct XmlDocument.Load method for speed up the loading process.

当我发现无处在互联网上/文件如何执行此加载进度的方式:无代表/事件似乎存在。有什么办法来执行这项任务?具有那种functionnality对XML储蓄的目的可能是一个不错的。

By the way I found nowhere on internet/document on how to follow this loading progress: no delegates/events seem exist. Is there any way to perform this task ? Having the kind of functionnality for XML saving purpose could be a nice to have.

感谢

推荐答案

假设你是从这里流中读取数据是如何做到这一点(非完美)的例子... 基本上ProgressStreamWrapper包文件流,提高每当位置发生变化的事件。

Assuming you are reading from a stream here is a (non-perfect) example of how to do it... Basically the ProgressStreamWrapper wraps the file stream and raises an event whenever Position is changed.

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Reading big file...");

        FileStream fileStream = File.OpenRead("c:\\temp\\bigfile.xml");
        ProgressStreamWrapper progressStreamWrapper = new ProgressStreamWrapper(fileStream);
        progressStreamWrapper.PositionChanged += (o, ea) => Console.WriteLine((double) progressStreamWrapper.Position / progressStreamWrapper.Length * 100 + "% complete");
        XmlReader xmlReader = XmlReader.Create(progressStreamWrapper);

        while (xmlReader.Read())
        {
            //read the xml document
        }

        Console.WriteLine("DONE");
        Console.ReadLine();
    }
}


public class ProgressStreamWrapper : Stream, IDisposable
{
    public ProgressStreamWrapper(Stream innerStream)
    {
        InnerStream = innerStream;
    }

    public Stream InnerStream { get; private set; }

    public override void Close()
    {
        InnerStream.Close();
    }

    void IDisposable.Dispose()
    {
        base.Dispose();
        InnerStream.Dispose();
    }

    public override void Flush()
    {
        InnerStream.Flush();
    }

    public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
    {
        return InnerStream.BeginRead(buffer, offset, count, callback, state);
    }

    public override int EndRead(IAsyncResult asyncResult)
    {
        int endRead = InnerStream.EndRead(asyncResult);
        OnPositionChanged();
        return endRead;
    }

    public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
    {
        return InnerStream.BeginWrite(buffer, offset, count, callback, state);
    }

    public override void EndWrite(IAsyncResult asyncResult)
    {
        InnerStream.EndWrite(asyncResult);
        OnPositionChanged(); ;
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
        long seek = InnerStream.Seek(offset, origin);
        OnPositionChanged();
        return seek;
    }

    public override void SetLength(long value)
    {
        InnerStream.SetLength(value);
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        int read = InnerStream.Read(buffer, offset, count);
        OnPositionChanged();
        return read;
    }

    public override int ReadByte()
    {
        int readByte = InnerStream.ReadByte();
        OnPositionChanged();
        return readByte;
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        InnerStream.Write(buffer, offset, count);
        OnPositionChanged();
    }

    public override void WriteByte(byte value)
    {
        InnerStream.WriteByte(value);
        OnPositionChanged();
    }

    public override bool CanRead
    {
        get { return InnerStream.CanRead; }
    }

    public override bool CanSeek
    {
        get { return InnerStream.CanSeek; }
    }

    public override bool CanTimeout
    {
        get { return InnerStream.CanTimeout; }
    }

    public override bool CanWrite
    {
        get { return InnerStream.CanWrite; }
    }

    public override long Length
    {
        get { return InnerStream.Length; }
    }

    public override long Position
    {
        get { return InnerStream.Position; }
        set
        {
            InnerStream.Position = value;
            OnPositionChanged();
        }
    }

    public event EventHandler PositionChanged;

    protected virtual void OnPositionChanged()
    {
        if (PositionChanged != null)
        {
            PositionChanged(this, EventArgs.Empty);
        }
    }

    public override int ReadTimeout
    {
        get { return InnerStream.ReadTimeout; }
        set { InnerStream.ReadTimeout = value; }
    }

    public override int WriteTimeout
    {
        get { return InnerStream.WriteTimeout; }
        set { InnerStream.WriteTimeout = value; }
    }
}