Skip to content

Instantly share code, notes, and snippets.

@dbones
Created March 1, 2014 22:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dbones/9298655 to your computer and use it in GitHub Desktop.
Save dbones/9298655 to your computer and use it in GitHub Desktop.
StreamCopy - Copy the contents from one stream to another, it also implements the INPC to allow updating of the UI of number of bytes copied and also the bytes per second (minimal testing applied)
public class StreamCopy : INotifyPropertyChanged
{
private readonly Stream _source;
private readonly Stream _destination;
private readonly int _bufferSize;
private readonly TransferStatus _transferStatus;
private long _numberOfBytesCopied;
internal StreamCopy(Stream source, Stream destination, int bufferSize = 1024)
{
_source = source;
_destination = destination;
_bufferSize = bufferSize;
_transferStatus = new TransferStatus(_bufferSize);
NumberOfBytesCopied = 0;
}
public long NumberOfBytesCopied
{
get { return _numberOfBytesCopied; }
private set
{
_numberOfBytesCopied = value;
OnPropertyChanged("NumberOfBytesCopied");
}
}
public long BytesPerSecond { get { return _transferStatus.BytesPerSecond; } }
public void Copy()
{
_transferStatus.AddTransferTime(DateTime.Now);
CopyStream(_source, _destination);
}
private void CopyStream(Stream src, Stream dest)
{
var buffer = new byte[_bufferSize];
int len;
while ((len = src.Read(buffer, 0, buffer.Length)) > 0)
{
dest.Write(buffer, 0, len);
NumberOfBytesCopied += len;
_transferStatus.AddTransferTime(DateTime.Now);
}
}
class TransferStatus
{
private readonly long _numberOfBytesInATransaction;
private readonly int _numberOfTransactionsToObserve;
private readonly Queue<DateTime> _times;
public TransferStatus(long numberOfBytesInATransaction, int numberOfTransactionsToObserve = 100)
{
_numberOfBytesInATransaction = numberOfBytesInATransaction;
_numberOfTransactionsToObserve = numberOfTransactionsToObserve;
_times = new Queue<DateTime>(numberOfTransactionsToObserve);
}
public long BytesPerSecond { get; private set; }
public void AddTransferTime(DateTime time)
{
if (_times.Count == _numberOfTransactionsToObserve)
{
_times.Dequeue();
}
_times.Enqueue(time);
if (_times.Count == 1)
{
BytesPerSecond = 0;
return;
}
var first = _times.First();
var last = _times.Last();
var timeTaken = last - first;
var totalBytes = _times.Count * _numberOfBytesInATransaction;
var speed = totalBytes / timeTaken.TotalMilliseconds;
BytesPerSecond = (long)(speed * 1000);
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment