private void RecursiveCopy(IElement srcelem, IDirectory dstdirpar) { if(srcelem.IsDirectory) { IDirectory srcdir = (IDirectory) srcelem; IElement dstelem = dstdirpar.GetChild(srcdir.Name); // TODO: try catch if(dstelem != null) { throw new Exception(dstelem.FullName + " already exists."); } IDirectory dstdir = dstdirpar.CreateDirectory(srcdir.Name); // TODO: try catch foreach(IDirectory srcsub in srcdir.GetDirectories()) { // TODO: try catch if(!_cancel) RecursiveCopy(srcsub, dstdir); } foreach(IFile srcsub in srcdir.GetFiles()) { // TODO: try catch if(!_cancel) RecursiveCopy(srcsub, dstdir); } } else { SingleCopy((IFile) srcelem, dstdirpar); } }
private void SingleCopy(IFile srcfile, IDirectory dstdirpar) { IElement dstelem = dstdirpar.GetChild(srcfile.Name); // TODO: try catch if(dstelem != null) { throw new Exception(dstelem.FullName + " already exists."); } _wnd.Invoke( (FVoid) delegate { _wnd.Line1 = "Copying " + srcfile.FullName + " ..."; } ); bool retry; do { retry = false; try { using(Stream srcstm = srcfile.Open(true, false)) { using(Stream dststm = dstdirpar.CreateFileAndOpen(srcfile.Name, srcfile.Size, srcfile.ContentType, false, true) /* dstfile.Open(false, true) */) { long pos = 0; long len = srcstm.Length; byte[] buf = new byte[4096]; // Setting a lower value seems to help against timeouts at Amazon S3 (before: 65536) while(len > 0) { int now = (len > buf.Length) ? buf.Length : (int) len; now = srcstm.Read (buf, 0, now); dststm.Write(buf, 0, now); dststm.Flush(); len -= now; pos += now; _wnd.Invoke( (FVoid) delegate { _wnd.Line2 = ((pos + 1023) >> 10) + " KB copied."; } ); if(_cancel) break; } } } } catch(Exception ex) { switch(MessageBox.Show("Failed to copy '" + srcfile.FullName + "' to '" + dstdirpar.FullName + "'.\n" + ex.Message + "\n\nDo you want to retry?\nSelect 'Cancel' to abort.", "Error", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Error)) { case DialogResult.Yes: retry = true; break; case DialogResult.No: retry = false; break; case DialogResult.Cancel: _cancel = true; break; } try { dstelem = dstdirpar.GetChild(srcfile.Name); if(dstelem != null) dstelem.Delete(); } catch { } } } while(retry && !_cancel); _wnd.Invoke( (FVoid) delegate { _wnd.Line2 = null; } ); }