private void AsyncWriteFile() {
//open output file set length to prevent growth and file fragmentation and close it.
//We do this to prevent file fragmentation and make the write as fast as possible.
try {
_outfile = new FileStream(_outputfile, FileMode.Create, FileAccess.Write, FileShare.None, 8, FileOptions.WriteThrough);
//set file size to minimum of one buffer to cut down on fragmentation
_outfile.SetLength(_infilesize > CopyBufferSize ? _infilesize : CopyBufferSize);
_outfile.Close();
_outfile.Dispose();
} catch {
throw;
}
//open file for write unbuffered
try {
_outfile = new FileStream(_outputfile, FileMode.Open, FileAccess.Write, FileShare.None, 8, FileOptions.WriteThrough | FileFlagNoBuffering);
} catch {
throw;
}
var pctinc = 0.0;
var progress = pctinc;
//progress stuff
if (_reportprogress) {
pctinc = 100.00 / _numchunks;
}
while ((_totalbyteswritten < _infilesize) && !_readfailed) {
lock (Locker1) {
while (!_buffer2Dirty) Monitor.Wait(Locker1);
Buffer.BlockCopy(Buffer2, 0, Buffer3, 0, _bytesRead2);
_buffer2Dirty = false;
_totalbyteswritten = _totalbyteswritten + CopyBufferSize;
Monitor.PulseAll(Locker1);
//fancy dan in place percent update on each write.
if (this.OnProgress != null) {
this.OnProgress.Invoke(this, new CopyEventArgs() {
InFileName = _inputfile,
OutFileName = _outputfile,
BytesTransferred = _totalbyteswritten,
TotalBytes = _infilesize
});
}
if (_reportprogress) {
Console.SetCursorPosition(_origCol, _origRow);
if (progress < 101 - pctinc) {
progress = progress + pctinc;
Console.Write("%{0}", Math.Round(progress, 0));
}
}
}
try {
_outfile.Write(Buffer3, 0, CopyBufferSize);
} catch {
throw;
}
}
//close the file handle that was using unbuffered and write through
_outfile.Close();
_outfile.Dispose();
try {
_outfile = new FileStream(_outputfile, FileMode.Open, FileAccess.Write, FileShare.None, 8,
FileOptions.WriteThrough);
_outfile.SetLength(_infilesize);
_outfile.Close();
_outfile.Dispose();
} catch {
throw;
}
}