Skip to content

Commit 46efd07

Browse files
committed
增加HttpProgress
1 parent 307dccc commit 46efd07

File tree

2 files changed

+87
-5
lines changed

2 files changed

+87
-5
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
namespace System.Net.Http
2+
{
3+
/// <summary>
4+
/// 表示http进度
5+
/// </summary>
6+
public class HttpProgress
7+
{
8+
/// <summary>
9+
/// 获取文件总字节数
10+
/// </summary>
11+
public long? FileSize { get; }
12+
13+
/// <summary>
14+
/// 获取当前接收到的字节数
15+
/// </summary>
16+
public long RecvSize { get; }
17+
18+
/// <summary>
19+
/// 获取是否已完成
20+
/// </summary>
21+
public bool IsCompleted { get; }
22+
23+
/// <summary>
24+
/// http进度
25+
/// </summary>
26+
/// <param name="fileSize">文件总字节数</param>
27+
/// <param name="recvSize">当前完成的字节数</param>
28+
/// <param name="isCompleted">是否已完成</param>
29+
public HttpProgress(long? fileSize, long recvSize, bool isCompleted)
30+
{
31+
this.FileSize = fileSize;
32+
this.RecvSize = recvSize;
33+
this.IsCompleted = isCompleted;
34+
}
35+
}
36+
}

WebApiClientCore/System.Net.Http/HttpResponseMessageExtensions.cs

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,26 +54,72 @@ public static async Task SaveAsAsync(this HttpResponseMessage httpResponse, stri
5454
await httpResponse.SaveAsAsync(fileStream, cancellationToken).ConfigureAwait(false);
5555
}
5656

57+
/// <summary>
58+
/// 保存到目标流
59+
/// </summary>
60+
/// <param name="httpResponse"></param>
61+
/// <param name="destination">目标流</param>
62+
/// <param name="cancellationToken">取消令牌</param>
63+
/// <exception cref="ArgumentNullException"></exception>
64+
/// <exception cref="ArgumentException"></exception>
65+
/// <exception cref="OperationCanceledException"></exception>
66+
/// <returns></returns>
67+
public static async Task SaveAsAsync(this HttpResponseMessage httpResponse, Stream destination, CancellationToken cancellationToken = default)
68+
{
69+
if (destination == null)
70+
{
71+
throw new ArgumentNullException(nameof(destination));
72+
}
73+
74+
var source = await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
75+
await source.CopyToAsync(destination, cancellationToken).ConfigureAwait(false);
76+
}
5777

5878
/// <summary>
5979
/// 保存到目标流
6080
/// </summary>
6181
/// <param name="httpResponse"></param>
62-
/// <param name="stream">流</param>
82+
/// <param name="destination">目标流</param>
83+
/// <param name="progressChanged">进度变化</param>
6384
/// <param name="cancellationToken">取消令牌</param>
6485
/// <exception cref="ArgumentNullException"></exception>
6586
/// <exception cref="ArgumentException"></exception>
6687
/// <exception cref="OperationCanceledException"></exception>
6788
/// <returns></returns>
68-
public static async Task SaveAsAsync(this HttpResponseMessage httpResponse, Stream stream, CancellationToken cancellationToken = default)
89+
public static async Task SaveAsAsync(this HttpResponseMessage httpResponse, Stream destination, Action<HttpProgress> progressChanged, CancellationToken cancellationToken = default)
6990
{
70-
if (stream == null)
91+
if (destination == null)
7192
{
72-
throw new ArgumentNullException(nameof(stream));
93+
throw new ArgumentNullException(nameof(destination));
7394
}
7495

96+
var recvSize = 0L;
97+
var isCompleted = false;
98+
var fileSize = httpResponse.Content.Headers.ContentLength;
99+
100+
var buffer = new byte[8 * 1024];
75101
var source = await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
76-
await source.CopyToAsync(stream, cancellationToken).ConfigureAwait(false);
102+
103+
while (isCompleted == false && cancellationToken.IsCancellationRequested == false)
104+
{
105+
var length = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false);
106+
if (length == 0)
107+
{
108+
if (fileSize == null)
109+
{
110+
fileSize = recvSize;
111+
}
112+
isCompleted = true;
113+
}
114+
else
115+
{
116+
recvSize += length;
117+
await destination.WriteAsync(buffer, 0, length, cancellationToken).ConfigureAwait(false);
118+
await destination.FlushAsync(cancellationToken);
119+
}
120+
121+
progressChanged.Invoke(new HttpProgress(fileSize, recvSize, isCompleted));
122+
}
77123
}
78124
}
79125
}

0 commit comments

Comments
 (0)