Skip to content

Commit bc8d9eb

Browse files
committed
Merge pull request #45 from qiniu/develop
Release 6.1.1
2 parents b1161e6 + aafe9e3 commit bc8d9eb

14 files changed

+63
-169
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
## CHANGE LOG
22

3+
### v6.1.1
4+
2014-04-28 issue [#45](https://github.com/qiniu/csharp-sdk/pull/45)
5+
- [#41] [#42] 简化断点续上传,删除bput逻辑, 修复bug:>2.5GB文件上传失败
6+
- [#38] [#40] pfop 支持
7+
38
### v6.1.0
49

510
2014-02-18 issue [#37](https://github.com/qiniu/csharp-sdk/pull/37)

Docs/README.md

+5-28
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ DLL引用方式:
5858
C# SDK引用了第三方的开源项目 Json.NET,因此,您需要在项目中引用它
5959
项目地址:[http://json.codeplex.com](http://json.codeplex.com)
6060

61+
<a name=setup></a>
62+
## 初始化
6163
<a name=setup-key></a>
6264
### 配置密钥
6365

@@ -424,18 +426,8 @@ public static void PutFile(string bucket, string key, string fname)
424426
{
425427
var policy = new PutPolicy(bucket, 3600);
426428
string upToken = policy.Token();
427-
PutExtra extra = new PutExtra { Bucket = bucket };
429+
PutExtra extra = new PutExtra ();
428430
IOClient client = new IOClient();
429-
client.PutFinished += new EventHandler<PutRet>((o, ret) => {
430-
if (ret.OK)
431-
{
432-
Console.WriteLine("Hash: " + ret.Hash);
433-
}
434-
else
435-
{
436-
Console.WriteLine("Failed to PutFile");
437-
}
438-
});
439431
client.PutFile(upToken, key, fname, extra);
440432
}
441433
```
@@ -455,27 +447,12 @@ public static void ResumablePutFile(string bucket, string key, string fname)
455447
string upToken = policy.Token();
456448
Settings setting = new Settings();
457449
ResumablePutExtra extra = new ResumablePutExtra();
458-
extra.Bucket = bucket;
459450
ResumablePut client = new ResumablePut(setting, extra);
460-
client.Progress += new Action<float>((p) => {
461-
Console.WriteLine("当前进度:{0}%", p * 100);
462-
463-
});
464-
client.PutFinished += new EventHandler<CallRet>((o, ret) => {
465-
if (ret.OK)
466-
{
467-
Console.WriteLine("上传成功:{0}",ret.Response);
468-
}
469-
else
470-
{
471-
Console.WriteLine("上传失败:{0}", ret.Response);
472-
}
473-
});
474451
client.PutFile(upToken, fname, Guid.NewGuid().ToString());
475452
}
476453
```
477454

478-
ResumablePut采用分快上传,各快之间采用并行上传,通过注册事件Progress可以获取当前文件上传进度,同时您也可以通过注册ResumablePutExtra以下两个事件监听当前上传进度以及成功情况
455+
ResumablePut采用分快上传,各快之间采用并行上传,可以通过注册ResumablePutExtra以下两个事件监听当前上传进度以及成功情况
479456

480457
```c#
481458
public event EventHandler<PutNotifyEvent> Notify;
@@ -498,7 +475,7 @@ public event EventHandler<PutNotifyErrorEvent> NotifyErr;
498475

499476
其中<domain>是bucket所对应的域名。七牛云存储为每一个bucket提供一个默认域名。默认域名可以到[七牛云存储开发者平台](https://portal.qiniu.com/)中,空间设置的域名设置一节查询。用户也可以将自有的域名绑定到bucket上,用户可以通过自有域名访问七牛云存储。
500477

501-
**注意: key必须采用utf8编码,如使用非utf8编码访问七牛云存储将反馈错误**
478+
**注意: key必须采用utf8编码,如使用非utf8编码访问七牛云存储将返回错误**
502479

503480
<a name=private-download></a>
504481
#### 私有资源下载

Qiniu.Test/IO/Resumable/ResumablePutTest.cs

-8
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ public void ResumablePutFileTest()
3434
ResumablePut target = new ResumablePut(putSetting, extra); // TODO: 初始化为适当的值
3535
Console.WriteLine ("extra.Bucket:"+Bucket);
3636
string upToken = new PutPolicy(Bucket).Token(new Qiniu.Auth.digest.Mac());
37-
target.Progress += new Action<float>(target_Progress);
3837
TmpFIle file=new TmpFIle(1024*1024*4);
3938
target.PutFinished += new EventHandler<CallRet> ((o,e) => {
4039
file.Del ();
@@ -63,12 +62,5 @@ void extra_Notify(object sender, PutNotifyEvent e)
6362
PrintLn(e.BlkSize.ToString());
6463
PrintLn(e.Ret.offset.ToString());
6564
}
66-
void target_Progress(float obj)
67-
{
68-
if (obj > 0.999999)
69-
{
70-
PrintLn((obj * 100).ToString() + "%");
71-
}
72-
}
7365
}
7466
}

Qiniu/IO/Resumable/ResumablePut.cs

+35-116
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.IO;
34
using System.Text;
45
#if NET40
@@ -21,14 +22,6 @@ public class ResumablePut
2122
private const int blockMashk = (1 << blockBits) - 1;
2223
private static int BLOCKSIZE = 4 * 1024 * 1024;
2324

24-
#region 记录总文件大小,用于计算上传百分比
25-
26-
private long fsize;
27-
private float chunks;
28-
private float uploadedChunks = 0;
29-
30-
#endregion
31-
3225
/// <summary>
3326
/// 上传完成事件
3427
/// </summary>
@@ -37,10 +30,6 @@ public class ResumablePut
3730
/// 上传Failure事件
3831
/// </summary>
3932
public event EventHandler<CallRet> PutFailure;
40-
/// <summary>
41-
/// 进度提示事件
42-
/// </summary>
43-
public event Action<float> Progress;
4433

4534
Settings putSetting;
4635

@@ -71,7 +60,6 @@ public ResumablePutExtra Extra
7160
/// <param name="extra"></param>
7261
public ResumablePut(Settings putSetting, ResumablePutExtra extra)
7362
{
74-
extra.chunkSize = putSetting.ChunkSize;
7563
this.putSetting = putSetting;
7664
this.extra = extra;
7765
}
@@ -88,36 +76,23 @@ public CallRet PutFile(string upToken, string localFile, string key)
8876
{
8977
throw new Exception(string.Format("{0} does not exist", localFile));
9078
}
79+
9180
PutAuthClient client = new PutAuthClient(upToken);
9281
CallRet ret;
9382
using (FileStream fs = File.OpenRead(localFile))
9483
{
9584
int block_cnt = block_count(fs.Length);
96-
fsize = fs.Length;
97-
chunks = fsize / extra.chunkSize + 1;
85+
long fsize = fs.Length;
9886
extra.Progresses = new BlkputRet[block_cnt];
99-
//并行上传
100-
#if NET35||NET20
87+
byte[] byteBuf = new byte[BLOCKSIZE];
88+
int readLen = BLOCKSIZE;
10189
for (int i = 0; i < block_cnt; i++)
10290
{
103-
#elif NET40
104-
Parallel.For(0, block_cnt, (i) =>{
105-
#endif
106-
107-
int readLen = BLOCKSIZE;
108-
if ((i + 1) * BLOCKSIZE > fsize)
109-
readLen = (int)(fsize - i * BLOCKSIZE);
110-
byte[] byteBuf = new byte[readLen];
111-
#if NET40
112-
lock (fs)
113-
{
114-
#endif
115-
fs.Seek(i * BLOCKSIZE, SeekOrigin.Begin);
91+
if (i == block_cnt - 1) {
92+
readLen = (int)(fsize - (long)i * BLOCKSIZE);
93+
}
94+
fs.Seek((long)i * BLOCKSIZE, SeekOrigin.Begin);
11695
fs.Read(byteBuf, 0, readLen);
117-
#if NET40
118-
}
119-
#endif
120-
//并行上传BLOCK
12196
BlkputRet blkRet = ResumableBlockPut(client, byteBuf, i, readLen);
12297
if (blkRet == null)
12398
{
@@ -127,19 +102,11 @@ public CallRet PutFile(string upToken, string localFile, string key)
127102
{
128103
extra.OnNotify(new PutNotifyEvent(i, readLen, extra.Progresses[i]));
129104
}
130-
#if NET35||NET20
131105
}
132-
#elif NET40
133-
});
134-
#endif
135-
ret = Mkfile(client, key, fs.Length);
106+
ret = Mkfile(client, key, fsize);
136107
}
137108
if (ret.OK)
138109
{
139-
if (Progress != null)
140-
{
141-
Progress(1.0f);
142-
}
143110
if (PutFinished != null)
144111
{
145112
PutFinished(this, ret);
@@ -155,104 +122,56 @@ public CallRet PutFile(string upToken, string localFile, string key)
155122
return ret;
156123
}
157124

158-
159-
/// <summary>
160-
/// 百分比进度提示
161-
/// </summary>
162-
private void progress()
163-
{
164-
uploadedChunks++;
165-
if (Progress != null)
166-
{
167-
Progress((float)uploadedChunks / chunks);
168-
}
169-
}
170-
171125
private BlkputRet ResumableBlockPut(Client client, byte[] body, int blkIdex, int blkSize)
172126
{
173-
int bodyLength;
174-
int chunkSize = extra.chunkSize;
175127
#region Mkblock
176-
if (extra.Progresses[blkIdex] == null)
128+
uint crc32 = CRC32.CheckSumBytes(body, blkSize);
129+
for (int i = 0; i < putSetting.TryTimes; i++)
177130
{
178-
bodyLength = chunkSize < blkSize ? chunkSize : blkSize;
179-
byte[] firstChunk = new byte[bodyLength];
180-
Array.Copy(body, 0, firstChunk, 0, bodyLength);
181-
uint crc32 = CRC32.CheckSumBytes(firstChunk);
182-
for (int i = 0; i < putSetting.TryTimes; i++)
131+
try
183132
{
184-
extra.Progresses[blkIdex] = Mkblock(client, firstChunk, body.Length);
185-
if (extra.Progresses[blkIdex] == null || crc32 != extra.Progresses[blkIdex].crc32)
186-
{
187-
if (i == (putSetting.TryTimes - 1))
188-
{
189-
return null;
190-
}
191-
continue;
192-
}
193-
else
194-
{
195-
progress();
196-
break;
197-
}
133+
extra.Progresses[blkIdex] = Mkblock(client, body, blkSize);
198134
}
199-
}
200-
#endregion
201-
202-
#region PutBlock
203-
while (extra.Progresses[blkIdex].offset < blkSize)
204-
{
205-
bodyLength = (chunkSize < (blkSize - extra.Progresses[blkIdex].offset)) ? chunkSize : (int)(blkSize - extra.Progresses[blkIdex].offset);
206-
byte[] chunk = new byte[bodyLength];
207-
Array.Copy(body, extra.Progresses[blkIdex].offset, chunk, 0, bodyLength);
208-
for (int i = 0; i < putSetting.TryTimes; i++)
135+
catch (Exception ee)
209136
{
210-
extra.Progresses[blkIdex] = BlockPut(client, extra.Progresses[blkIdex], new MemoryStream(chunk), bodyLength);
211-
if (extra.Progresses[blkIdex] == null)
137+
if (i == (putSetting.TryTimes - 1))
212138
{
213-
if (i == (putSetting.TryTimes - 1))
214-
{
215-
return null;
216-
}
217-
continue;
139+
throw ee;
218140
}
219-
else
141+
System.Threading.Thread.Sleep(1000);
142+
continue;
143+
}
144+
if (extra.Progresses[blkIdex] == null || crc32 != extra.Progresses[blkIdex].crc32)
145+
{
146+
if (i == (putSetting.TryTimes - 1))
220147
{
221-
uploadedChunks++;
222-
if (Progress != null)
223-
{
224-
Progress((float)uploadedChunks / chunks);
225-
}
226-
break;
148+
return null;
227149
}
150+
System.Threading.Thread.Sleep(1000);
151+
continue;
152+
}
153+
else
154+
{
155+
break;
228156
}
229157
}
230158
#endregion
159+
231160
return extra.Progresses[blkIdex];
232-
}
161+
}
233162

234-
private BlkputRet Mkblock(Client client, byte[] firstChunk, long blkSize)
163+
private BlkputRet Mkblock(Client client, byte[] firstChunk, int blkSize)
235164
{
236165
string url = string.Format("{0}/mkblk/{1}", Config.UP_HOST, blkSize);
237-
CallRet callRet = client.CallWithBinary(url, "application/octet-stream", new MemoryStream(firstChunk), firstChunk.Length);
166+
167+
CallRet callRet = client.CallWithBinary(url, "application/octet-stream",new MemoryStream(firstChunk, 0, blkSize),blkSize);
238168
if (callRet.OK)
239169
{
240170
return QiniuJsonHelper.ToObject<BlkputRet>(callRet.Response);
241171
}
242172
return null;
243173
}
244174

245-
private BlkputRet BlockPut(Client client, BlkputRet ret, Stream body, long length)
246-
{
247-
string url = string.Format("{0}/bput/{1}/{2}", Config.UP_HOST, ret.ctx, ret.offset);
248-
CallRet callRet = client.CallWithBinary(url, "application/octet-stream", body, length);
249-
if (callRet.OK)
250-
{
251-
return QiniuJsonHelper.ToObject<BlkputRet>(callRet.Response);
252-
}
253-
return null;
254-
}
255-
256175
private CallRet Mkfile(Client client, string key, long fsize)
257176
{
258177
StringBuilder urlBuilder = new StringBuilder();

Qiniu/IO/Resumable/ResumablePutRet.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ public class BlkputRet
1313
[JsonProperty("crc32")]
1414
public UInt32 crc32;
1515
[JsonProperty("offset")]
16-
public UInt32 offset;
16+
public ulong offset;
1717
}
1818
}

Qiniu/IO/Resumable/Settings.cs

+6-6
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@ namespace Qiniu.IO.Resumable
66
/// </summary>
77
public class Settings
88
{
9-
int chunkSize;
10-
119
/// <summary>
1210
/// chunk大小,默认为4MB;
11+
/// 兼容保留
1312
/// </summary>
1413
public int ChunkSize {
15-
get { return chunkSize; }
16-
set { chunkSize = value; }
14+
get;
15+
set;
1716
}
1817

1918
int tryTimes;
@@ -32,8 +31,9 @@ public int TryTimes {
3231
/// <param name="chunkSize">chunk大小,默认为4MB</param>
3332
/// <param name="tryTimes">失败重试次数,默认为3</param>
3433
public Settings (int chunkSize=1 << 22, int tryTimes=3)
35-
{
36-
this.chunkSize = chunkSize;
34+
{
35+
//chunkSize 已经删除,兼容保留
36+
3737
this.tryTimes = tryTimes;
3838
}
3939
}

Qiniu/Qiniu.2.0.csproj

+1-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
<TargetFrameworkProfile />
1616
</PropertyGroup>
1717
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
18-
<PlatformTarget>x86</PlatformTarget>
1918
<DebugSymbols>true</DebugSymbols>
2019
<DebugType>full</DebugType>
2120
<Optimize>false</Optimize>
@@ -101,4 +100,4 @@
101100
<None Include="app.config" />
102101
</ItemGroup>
103102
<ItemGroup />
104-
</Project>
103+
</Project>

Qiniu/Qiniu.4.0.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<TargetFrameworkProfile />
1616
</PropertyGroup>
1717
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
18-
<PlatformTarget>x86</PlatformTarget>
18+
<PlatformTarget>AnyCPU</PlatformTarget>
1919
<DebugSymbols>true</DebugSymbols>
2020
<DebugType>full</DebugType>
2121
<Optimize>false</Optimize>

0 commit comments

Comments
 (0)