From eca6b228015c056c324d83e77e200bea11707973 Mon Sep 17 00:00:00 2001 From: icattlecoder Date: Wed, 16 Oct 2013 14:33:48 +0800 Subject: [PATCH 1/2] fix --- Qiniu.Test/IO/Resumable/ResumablePutTest.cs | 6 +- Qiniu/IO/Resumable/ResumablePut.cs | 63 ++++++++++++++------- Qiniu/IO/Resumable/ResumablePutExtra.cs | 4 +- 3 files changed, 51 insertions(+), 22 deletions(-) diff --git a/Qiniu.Test/IO/Resumable/ResumablePutTest.cs b/Qiniu.Test/IO/Resumable/ResumablePutTest.cs index aa771be2..3cbb0915 100644 --- a/Qiniu.Test/IO/Resumable/ResumablePutTest.cs +++ b/Qiniu.Test/IO/Resumable/ResumablePutTest.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Specialized; using System.IO; using NUnit.Framework; using Qiniu.IO.Resumable; @@ -25,6 +26,9 @@ public void ResumablePutFileTest() Settings putSetting = new Settings(); // TODO: 初始化为适当的值 string key=NewKey; ResumablePutExtra extra = new ResumablePutExtra(); + NameValueCollection nc = new NameValueCollection (); + nc.Add("x:username","qiniu"); + extra.CallbackParams = nc; extra.Notify += new EventHandler(extra_Notify); extra.NotifyErr += new EventHandler(extra_NotifyErr); extra.Bucket = Bucket; @@ -39,7 +43,7 @@ public void ResumablePutFileTest() RSHelper.RSDel (Bucket, key); } }); - target.PutFile (upToken, file.FileName, key); + CallRet ret =target.PutFile (upToken, file.FileName, key); //Action a = new Action (() => //{ diff --git a/Qiniu/IO/Resumable/ResumablePut.cs b/Qiniu/IO/Resumable/ResumablePut.cs index 4abe0cde..ddb304f1 100644 --- a/Qiniu/IO/Resumable/ResumablePut.cs +++ b/Qiniu/IO/Resumable/ResumablePut.cs @@ -19,15 +19,25 @@ public class ResumablePut private const int blockMashk = (1 << blockBits) - 1; private static int BLOCKSIZE = 4 * 1024 * 1024; private const string UNDEFINED_KEY = "?"; + #region 记录总文件大小,用于计算上传百分比 + private long fsize; private float chunks; private float uploadedChunks = 0; + #endregion + /// /// 上传完成事件 /// public event EventHandler PutFinished; + + /// + /// 上传Failure事件 + /// + public event EventHandler PutFailure; + /// /// 进度提示事件 /// @@ -71,7 +81,7 @@ public ResumablePut (Settings putSetting, ResumablePutExtra extra) /// 上传Token /// key /// 本地文件名 - public void PutFile (string upToken, string localFile, string key) + public CallRet PutFile (string upToken, string localFile, string key) { PutAuthClient client = new PutAuthClient (upToken); using (FileStream fs = File.OpenRead(localFile)) { @@ -80,8 +90,7 @@ public void PutFile (string upToken, string localFile, string key) chunks = fsize / extra.chunkSize + 1; extra.Progresses = new BlkputRet[block_cnt]; //并行上传 - Parallel.For (0, block_cnt, (i) => - { + Parallel.For (0, block_cnt, (i) => { int readLen = BLOCKSIZE; if ((i + 1) * BLOCKSIZE > fsize) readLen = (int)(fsize - i * BLOCKSIZE); @@ -89,27 +98,34 @@ public void PutFile (string upToken, string localFile, string key) lock (fs) { fs.Seek (i * BLOCKSIZE, SeekOrigin.Begin); fs.Read (byteBuf, 0, readLen); + BlkputRet blkRet = ResumableBlockPut (client, byteBuf, i, readLen); + if (blkRet == null) { extra.OnNotifyErr (new PutNotifyErrorEvent (i, readLen, "Make Block Error")); } else { extra.OnNotify (new PutNotifyEvent (i, readLen, extra.Progresses [i])); - } - } + } + } }); if (string.IsNullOrEmpty (key)) { key = UNDEFINED_KEY; } CallRet ret = Mkfile (client, key, fs.Length); - if (Progress != null) { - Progress (1.0f); - } - if (PutFinished != null) { - PutFinished (this, ret); + if (ret.OK) { + if (Progress != null) { + Progress (1.0f); + } + if (PutFinished != null) { + PutFinished (this, ret); + } + } else { + if (PutFailure != null) { + PutFailure (this, ret); + } } - + return ret; } - } /// @@ -147,8 +163,9 @@ private BlkputRet ResumableBlockPut (Client client, byte[] body, int blkIdex, in } } #endregion + #region PutBlock - while (extra.Progresses[blkIdex].offset < blkSize) { + while (extra.Progresses [blkIdex].offset < blkSize) { bodyLength = (chunkSize < (blkSize - extra.Progresses [blkIdex].offset)) ? chunkSize : (int)(blkSize - extra.Progresses [blkIdex].offset); byte[] chunk = new byte[bodyLength]; Array.Copy (body, extra.Progresses [blkIdex].offset, chunk, 0, bodyLength); @@ -194,17 +211,23 @@ private BlkputRet BlockPut (Client client, BlkputRet ret, Stream body, long leng private CallRet Mkfile (Client client, string key, long fsize) { - EntryPath entry = new EntryPath (extra.Bucket, key); - string url = string.Format ("{0}/rs-mkfile/{1}/fsize/{2}/", Config.UP_HOST, entry.Base64EncodedURI, fsize); + StringBuilder urlBuilder = new StringBuilder (); + + urlBuilder.AppendFormat ("{0}/mkfile/{1}/key/{2}", Config.UP_HOST, fsize, key.ToBase64URLSafe ()); if (!string.IsNullOrEmpty (extra.MimeType)) { - url += (string.Format ("/mimeType/{0}", extra.MimeType.ToBase64URLSafe ())); + urlBuilder.AppendFormat ("/mimeType/{0}", extra.MimeType.ToBase64URLSafe ()); } if (!string.IsNullOrEmpty (extra.CustomMeta)) { - url += (string.Format ("/meta/{0}", extra.CustomMeta.ToBase64URLSafe ())); + urlBuilder.AppendFormat ("/meta/{0}", extra.CustomMeta.ToBase64URLSafe ()); } - if (!string.IsNullOrEmpty (extra.CallbackParams)) { - url += (string.Format ("/params/{0}", extra.CallbackParams.ToBase64URLSafe ())); + if (extra.CallbackParams != null && extra.CallbackParams.Count > 0) { + StringBuilder sb = new StringBuilder (); + foreach (string _key in extra.CallbackParams.Keys) { + sb.AppendFormat ("/{0}/{1}", _key, extra.CallbackParams [_key].ToBase64URLSafe ()); + } + urlBuilder.Append (sb.ToString ()); } + int proCount = extra.Progresses.Length; using (Stream body = new MemoryStream()) { for (int i = 0; i < proCount; i++) { @@ -215,7 +238,7 @@ private CallRet Mkfile (Client client, string key, long fsize) } } body.Seek (0, SeekOrigin.Begin); - return client.CallWithBinary (url, "text/plain", body, body.Length); + return client.CallWithBinary (urlBuilder.ToString (), "text/plain", body, body.Length); } } diff --git a/Qiniu/IO/Resumable/ResumablePutExtra.cs b/Qiniu/IO/Resumable/ResumablePutExtra.cs index 78506b6d..52894b70 100644 --- a/Qiniu/IO/Resumable/ResumablePutExtra.cs +++ b/Qiniu/IO/Resumable/ResumablePutExtra.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Specialized; namespace Qiniu.IO.Resumable { @@ -69,7 +70,8 @@ public PutNotifyErrorEvent (int blkIdx, int blkSize, string error) /// public class ResumablePutExtra { - public string CallbackParams; + //key format as: "x:var" + public NameValueCollection CallbackParams; public string Bucket; public string CustomMeta; public string MimeType; From 9f853b0733fac817b4eb097a4045848d46f875bb Mon Sep 17 00:00:00 2001 From: icattlecoder Date: Wed, 16 Oct 2013 14:39:05 +0800 Subject: [PATCH 2/2] fix --- Qiniu/IO/Resumable/ResumablePut.cs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/Qiniu/IO/Resumable/ResumablePut.cs b/Qiniu/IO/Resumable/ResumablePut.cs index ddb304f1..bb687cc7 100644 --- a/Qiniu/IO/Resumable/ResumablePut.cs +++ b/Qiniu/IO/Resumable/ResumablePut.cs @@ -32,12 +32,10 @@ public class ResumablePut /// 上传完成事件 /// public event EventHandler PutFinished; - /// /// 上传Failure事件 /// public event EventHandler PutFailure; - /// /// 进度提示事件 /// @@ -98,15 +96,15 @@ public CallRet PutFile (string upToken, string localFile, string key) lock (fs) { fs.Seek (i * BLOCKSIZE, SeekOrigin.Begin); fs.Read (byteBuf, 0, readLen); + } + BlkputRet blkRet = ResumableBlockPut (client, byteBuf, i, readLen); - BlkputRet blkRet = ResumableBlockPut (client, byteBuf, i, readLen); - - if (blkRet == null) { - extra.OnNotifyErr (new PutNotifyErrorEvent (i, readLen, "Make Block Error")); - } else { - extra.OnNotify (new PutNotifyEvent (i, readLen, extra.Progresses [i])); - } - } + if (blkRet == null) { + extra.OnNotifyErr (new PutNotifyErrorEvent (i, readLen, "Make Block Error")); + } else { + extra.OnNotify (new PutNotifyEvent (i, readLen, extra.Progresses [i])); + } + }); if (string.IsNullOrEmpty (key)) { key = UNDEFINED_KEY;