public static object Deserialize(string path)
{
using (Stream stream = File.Open(path, FileMode.Open))
{
BinaryFormatter bformatter = new BinaryFormatter();
return bformatter.Deserialize(stream);
}
}
SomeClass someObject = (SomeClass)Deserialize(savePath);
我想创建一个包含自身进度的反序列化过程。 所以可能某种IEnumerator每帧更新我的进度字段。 是否可以在读取文件时跟踪Formatter的位置?
当我反序列化大文件时,我想知道它是怎么回事......
答案 0 :(得分:6)
我认为最简单的方法是通过包装正在反序列化的Stream来跟踪它,并在Formatter读取它时跟踪位置。
public class ReadProgressStream : ContainerStream
{
private int _lastProgress = 0;
public ReadProgressStream(Stream stream) : base(stream)
{
if (stream.Length <= 0 || !stream.CanRead) throw new ArgumentException("stream");
}
public override int Read(byte[] buffer, int offset, int count)
{
int amountRead = base.Read(buffer, offset, count);
if (ProgressChanged != null)
{
int newProgress = (int)(Position * 100.0 / Length);
if (newProgress > _lastProgress)
{
_lastProgress = newProgress;
ProgressChanged(this, new ProgressChangedEventArgs(_lastProgress, null));
}
}
return amountRead;
}
public event ProgressChangedEventHandler ProgressChanged;
}
用法:
public static T Deserialize<T>(
Stream stream, ProgressChangedEventHandler callback)
{
using (ReadProgressStream rps = new ReadProgressStream(stream))
using (BufferedStream bs = new BufferedStream(rps))
{
rps.ProgressChanged += callback;
BinaryFormatter formatter = new BinaryFormatter();
return (T)formatter.Deserialize(bs);
}
}
ContainerStream:
public abstract class ContainerStream : Stream
{
private Stream _stream;
protected ContainerStream(Stream stream)
{
if (stream == null) throw new ArgumentNullException("stream");
_stream = stream;
}
protected Stream ContainedStream { get { return _stream; } }
public override bool CanRead { get { return _stream.CanRead; } }
public override bool CanSeek { get { return _stream.CanSeek; } }
public override bool CanWrite { get { return _stream.CanWrite; } }
public override void Flush() { _stream.Flush(); }
public override long Length { get { return _stream.Length; } }
public override long Position
{
get { return _stream.Position; }
set { _stream.Position = value; }
}
public override int Read(byte[] buffer, int offset, int count)
{
return _stream.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
return _stream.Seek(offset, origin);
}
public override void SetLength(long value)
{
_stream.SetLength(value);
}
public override void Write(byte[] buffer, int offset, int count)
{
_stream.Write(buffer, offset, count);
}
}