using System; using System.IO; using System.Threading; using System.Windows.Forms; namespace StrangeFileCopy { public partial class MainForm : Form { private string _status = "Ready"; private int _bufProgress; private int _reOpenProgress; private int _totalProgress; public MainForm() { InitializeComponent(); } private void FireButton_Click(object sender, EventArgs e) { var srcPath = FromTextBox.Text; var dstPath = ToTextBox.Text; if (string.IsNullOrWhiteSpace(srcPath) || string.IsNullOrWhiteSpace(dstPath)) { MessageBox.Show("Before start,fill `File From' and `To Folder'"); return; } var blkSize = (int)BufSizeUpDown.Value * 1024 * 1024; var reOpenTimes = (int)Math.Ceiling(ReOpenSizeUnDown.Value * 1024 / BufSizeUpDown.Value); var flush = FlushCheckBox.Checked; FireButton.Enabled = false; ConfigGroupBox.Enabled = false; new Thread(() => { FileStream src = null; FileStream dst = null; try { _status = "Opening Source"; src = File.OpenRead(srcPath); var srcLen = src.Length; long pos = 0; var buf = new byte[blkSize]; while (pos < srcLen) { //open dest and set position _status = "Opening Dest"; dst = File.OpenWrite(dstPath); dst.Position = pos; for (var i = 0; i < reOpenTimes; i++) { _status = "Reading Source"; var bi = 0; var read = 0; do { read = src.Read(buf, bi, blkSize - read); bi += read; _bufProgress = (int)(100 * (float)bi / blkSize); } while (read > 0 && bi < blkSize); _status = "Writing Dst"; dst.Write(buf, 0, bi); _status = "Flushing Dst"; if (flush) dst.Flush(true); _reOpenProgress = (int)(100 * (float)i / reOpenTimes); _totalProgress = (int)(100 * (float)src.Position / srcLen); if (src.Position == srcLen) break; } pos = src.Position; _status = "Closing Dst"; dst.Close(); } _status = "Done"; } catch (Exception exception) { _status = $"Error:{exception.Message}"; } finally { src?.Close(); dst?.Close(); } }).Start(); } private void UiUpdateTimer_Tick(object sender, EventArgs e) { CurrentOperationLabel.Text = _status; BufProgressBar.Value = _bufProgress; ReOpenProgressBar.Value = _reOpenProgress; TotalProgressBar.Value = _totalProgress; } private void FromTextBox_DragEnter(object sender, DragEventArgs e) { string[] files; e.Effect = e.Data.GetDataPresent(DataFormats.FileDrop) && (files = (string[])e.Data.GetData(DataFormats.FileDrop)).Length == 1 && File.Exists(files[0]) ? DragDropEffects.Copy : DragDropEffects.None; } private void FromTextBox_DragDrop(object sender, DragEventArgs e) { FromTextBox.Text = ((string[])e.Data.GetData(DataFormats.FileDrop))[0]; } private void ToTextBox_DragEnter(object sender, DragEventArgs e) { string[] files; e.Effect = e.Data.GetDataPresent(DataFormats.FileDrop) && (files = (string[])e.Data.GetData(DataFormats.FileDrop)).Length == 1 && Directory.Exists(files[0]) ? DragDropEffects.Copy : DragDropEffects.None; } private void ToTextBox_DragDrop(object sender, DragEventArgs e) { var to = ((string[])e.Data.GetData(DataFormats.FileDrop))[0]; new Thread(() => { Invoke(new Action(delegate { if (string.IsNullOrWhiteSpace(FromTextBox.Text)) { MessageBox.Show("Fill `File from' first!"); return; } var filename = Path.GetFileName(FromTextBox.Text); var dest = Path.Combine(to, filename); if (File.Exists(dest)) { if (DialogResult.Yes == MessageBox.Show("Target file exist,override it?")) { ToTextBox.Text = dest; } else { ToTextBox.Clear(); } } else { ToTextBox.Text = dest; } })); }).Start(); } } }