diff --git a/BaiduYunSync/BaiduYunSync.csproj b/BaiduYunSync/BaiduYunSync.csproj index 24d70bc..5cf5f05 100644 --- a/BaiduYunSync/BaiduYunSync.csproj +++ b/BaiduYunSync/BaiduYunSync.csproj @@ -84,6 +84,7 @@ + frmLogin.cs diff --git a/BaiduYunSync/Sync.cs b/BaiduYunSync/Sync.cs index 9f9c51c..fdb59e9 100644 --- a/BaiduYunSync/Sync.cs +++ b/BaiduYunSync/Sync.cs @@ -20,7 +20,14 @@ namespace BaiduYunSync Operation.StartUploadBlock += Operation_StartUploadBlock; Operation.ComplateUploadBlock += Operation_ComplateUploadBlock; Operation.UpdateComplate += Operation_UpdateComplate; + Operation.UploadSpeed += Operation_UploadSpeed; + } + private static void Operation_UploadSpeed(string filePath, int fileBolckNum, double totalSecond, long offset, long blockTotalLenth) + { + //LogSettings.StdInfo(filePath + "已用时:" + totalSecond.ToString("F2") + "秒"); + //LogSettings.StdInfo(filePath + " 平均速度:" + (offset / 1024 / totalSecond).ToString("0.00") + "KB/秒"); + //LogSettings.StdInfo(filePath + "已上传:" + (offset * 100.0 / blockTotalLenth).ToString("F2") + "%"); } private static void Operation_UpdateComplate(string filePath) diff --git a/BaiduYunSync/UploadSpeedInfoDao.cs b/BaiduYunSync/UploadSpeedInfoDao.cs new file mode 100644 index 0000000..848e3f4 --- /dev/null +++ b/BaiduYunSync/UploadSpeedInfoDao.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BaiduYunSync +{ + public class UploadSpeedInfoDao + { + /// + /// 耗费时间 + /// + public double TotalSecond { get; set; } + + /// + /// 已完成大小 + /// + public long Offset { get; set; } + + /// + /// 本块总大小 + /// + public long BlockTotalLenth { get; set; } + } +} diff --git a/NetDisk/Operation.cs b/NetDisk/Operation.cs index 0eee553..321d8ab 100644 --- a/NetDisk/Operation.cs +++ b/NetDisk/Operation.cs @@ -23,6 +23,16 @@ namespace NetDisk public static event ComplateUploadBlockHandle ComplateUploadBlock; + /// + /// 块失败事件 + /// + /// + /// + /// + public delegate void FailedUploadBlockHandle(string filePath, int failedBlockNum, int totalBlockNum); + + public static event FailedUploadBlockHandle FailedUploadBlock; + /// /// 初始化上传 /// @@ -51,6 +61,15 @@ namespace NetDisk public static event UpdateComplateHandle UpdateComplate; + /// + /// 上传速度 + /// + /// + /// + public delegate void UploadSpeedHandle(string filePath, int fileBolckNum, double totalSecond, long offset, long blockTotalLenth); + + public static event UploadSpeedHandle UploadSpeed; + public static QuotaResult GetQuota(Credential credential) { @@ -490,8 +509,8 @@ namespace NetDisk wc.Headers.Add(HttpRequestHeader.ContentType, "multipart/form-data; boundary=" + boundary); var str = "--" + boundary + "\r\nContent-Disposition: form-data; name=\"filename\"; filename=\"name\"\r\nContent-Type: application/octet-stream\r\n\r\n"; var str2 = "\r\n--" + boundary + "--\r\n"; - stream.Seek((long)blockid * 4 * 1024 * 1024, SeekOrigin.Begin); - var fdata = new byte[4 * 1024 * 1024]; + stream.Seek((long)blockid * UploadHelper.BlockLen, SeekOrigin.Begin); + var fdata = new byte[UploadHelper.BlockLen]; var len = stream.Read(fdata, 0, fdata.Length); if (len < fdata.Length) { @@ -500,7 +519,7 @@ namespace NetDisk fdata = arr; } var data = Encoding.UTF8.GetBytes(str).Concat(fdata).Concat(Encoding.UTF8.GetBytes(str2)).ToArray(); - var res = wc.UploadData("http://" + host + "/rest/2.0/pcs/superfile2?app_id=250528&method=upload&path=" + HttpUtility.UrlEncode(path) + "&uploadid=" + HttpUtility.UrlEncode(session.uploadid) + "&partseq=" + blockid + "&partoffset=" + (long)blockid * 4 * 1024 * 1024, data); + var res = wc.UploadData("http://" + host + "/rest/2.0/pcs/superfile2?app_id=250528&method=upload&path=" + HttpUtility.UrlEncode(path) + "&uploadid=" + HttpUtility.UrlEncode(session.uploadid) + "&partseq=" + blockid + "&partoffset=" + (long)blockid * UploadHelper.BlockLen, data); var obj = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(res)); if (obj.md5 != prop.blocks[blockid]) throw new Exception("MD5 mismatch."); if (ComplateUploadBlock != null) @@ -515,6 +534,79 @@ namespace NetDisk return new Result() { exception = ex }; } } + + private static Result UploadWithWebrequest(FileProperty prop, string path, InitUploadResult session, FileStream stream, int blockid, string host, Credential credential) + { + var boundary = GetBoundary(); + string url = $"http://{host}/rest/2.0/pcs/superfile2?app_id=250528&method=upload&path={HttpUtility.UrlEncode(path)}&uploadid={HttpUtility.UrlEncode(session.uploadid)}&partseq={blockid}&partoffset={(long)blockid * UploadHelper.BlockLen}"; + var webRequest = (HttpWebRequest)WebRequest.Create(url); + webRequest.Headers.Add("Cookie", credential); + //对发送的数据不使用缓存 + webRequest.AllowWriteStreamBuffering = false; + //设置获得响应的超时时间(300秒) + webRequest.Timeout = 300000; + webRequest.ContentType = "multipart/form-data; boundary=" + boundary; + webRequest.Method = "POST"; + var startBoundaryBytes = Encoding.ASCII.GetBytes("--" + boundary + "\r\nContent-Disposition: form-data; name=\"filename\"; filename=\"name\"\r\nContent-Type: application/octet-stream\r\n\r\n"); + var endBoundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n"); + stream.Seek((long)blockid * UploadHelper.BlockLen, SeekOrigin.Begin); + var fdata = new byte[UploadHelper.BlockLen]; + var len = stream.Read(fdata, 0, fdata.Length); + if (len < fdata.Length) + { + var arr = new byte[len]; + Array.Copy(fdata, arr, len); + fdata = arr; + } + var fdataStream = new MemoryStream(fdata); + long totalLen = len + startBoundaryBytes.Length + endBoundaryBytes.Length; + webRequest.ContentLength = totalLen; + try + { + int bufferLen = 4 * 1024; + byte[] buffer = new byte[bufferLen]; + long offset = 0; + DateTime startTime = DateTime.Now; + Stream postStream = webRequest.GetRequestStream(); + postStream.Write(startBoundaryBytes, 0, startBoundaryBytes.Length); + do + { + var size = fdataStream.Read(buffer, 0, bufferLen); + if (size <= 0) + { + break; + } + offset += size; + postStream.Write(buffer, 0, size); + TimeSpan span = DateTime.Now - startTime; + double second = span.TotalSeconds; + if (UploadSpeed != null) + { + UploadSpeed(prop.path, blockid + 1, second, offset, fdata.LongLength); + } + //Console.WriteLine("已用时:" + second.ToString("F2") + "秒"); + //Console.WriteLine(" 平均速度:" + (offset / 1024 / second).ToString("0.00") + "KB/秒"); + //Console.WriteLine("已上传:" + (offset * 100.0 / fdata.Length).ToString("F2") + "%"); + } while (true); + postStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length); + postStream.Close(); + var responseSteam = webRequest.GetResponse().GetResponseStream(); + StreamReader sr = new StreamReader(responseSteam, Encoding.UTF8); + var obj = JsonConvert.DeserializeObject(sr.ReadToEnd()); + if (obj.md5 != prop.blocks[blockid]) throw new Exception("MD5 mismatch."); + if (ComplateUploadBlock != null) + { + ComplateUploadBlock(prop.path, blockid + 1, prop.blocks.Length); + } + return new Result() { success = true }; + } + catch (Exception ex) + { + + return new Result() { exception = ex }; + } + } + public static CommitUploadResult CommitUpload(FileProperty prop, string path, InitUploadResult session, Credential credential) { try @@ -555,6 +647,7 @@ namespace NetDisk for(int i = 0; i < prop.blocks.Length; i++) { var res = UploadBlock(prop, remotepath, session, fs, i, servers.servers[0], credential); + //var res = UploadWithWebrequest(prop, remotepath, session, fs, i, servers.servers[0], credential); if (!res.success) throw res.exception; } } diff --git a/NetDisk/UploadHelper.cs b/NetDisk/UploadHelper.cs index f2e88df..ffd7a78 100644 --- a/NetDisk/UploadHelper.cs +++ b/NetDisk/UploadHelper.cs @@ -9,6 +9,11 @@ namespace NetDisk { public static class UploadHelper { + /// + /// 每块大小 + /// + public const int BlockLen = 4 * 1024 * 1024; + public static FileProperty GetFileProperty(string path) { var ret = new FileProperty() { path = path }; @@ -19,14 +24,14 @@ namespace NetDisk using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { var md5 = new MD5CryptoServiceProvider(); - var arr = new byte[4 * 1024 * 1024]; + var arr = new byte[BlockLen]; var len = fs.Read(arr, 0, 256 * 1024); ret.slice_md5 = ByteArrayToHexString(md5.ComputeHash(arr, 0, len)); fs.Seek(0, SeekOrigin.Begin); var blocks = new List(); while (true) { - len = fs.Read(arr, 0, 4 * 1024 * 1024); + len = fs.Read(arr, 0, BlockLen); if (len <= 0) break; blocks.Add(ByteArrayToHexString(md5.ComputeHash(arr, 0, len))); }