XFEExtension
【DLL】XFE各类拓展是一个C#的DLL库,旨在优化C#代码中常用语句的使用,并提供更简洁的访问方式,同时提供Xunit测试框架,快速搭建服务器/客户端,免费ChatGPTAPI接口,免费通讯服务器,XFE下载器,新增格式等
关注
0
Fork
0
Star
0
返回提交历史
Modified
XFEExtension.NetCore.Analyzer.Test/Program.cs
+22
-5
Modified
XFEExtension.NetCore/WebExtension/XFEDownloader.cs
+27
-10
Modified
XFEExtension.NetCore/XFETransform/IObjectInfo.cs
+2
-0
Modified
XFEExtension.NetCore/XFETransform/ObjectInfo.cs
+1
-1
Modified
XFEExtension.NetCore/XFETransform/SubObjects.cs
+1
-1
XFEstudio/XFEExtension
fix-修复XFE下载器不能暂停的bug fix-对象分析器输出时,子对象的ObjectPlace显示问题
2dcb3db
代码差异
5 个文件
+53
-17
@@ -1,15 +1,32 @@
1
using XFEExtension.NetCore.StringExtension;
1
using XFEExtension.NetCore.FileExtension;
2
using XFEExtension.NetCore.WebExtension;
2
3
3
4
namespace XFEExtension.NetCore.Analyzer.Test;
4
5
5
6
internal class Program
6
7
{
7
public static void Main(string[] args)
8
public static async Task Main(string[] args)
8
9
{
9
var testClass = new TestClass("测试名称", "测试描述内容123123123", 60)
10
var xFEDownloader = new XFEDownloader()
10
11
{
11
Tags = [["123", "321"], ["231", "132"]]
12
DownloadUrl = "https://www.xfegzs.com/com.xfegzs.xccchatroom.apk",
13
SavePath = @"D:\work\C#\OtherProject\XUnitConsole\XUnitConsole\bin\Debug\net8.0\com.xfegzs.xccchatroom.apk"
12
14
};
13
testClass.X();
15
xFEDownloader.BufferDownloaded += XFEDownloader_BufferDownloaded;
16
var task = Task.Run(async () =>
17
{
18
await Task.Delay(5000);
19
xFEDownloader.Pause();
20
await Console.Out.WriteLineAsync("已暂停,将于10秒后开始");
21
await Task.Delay(10000);
22
await xFEDownloader.Continue();
23
});
24
await xFEDownloader.Download();
25
await task;
26
}
27
28
private static void XFEDownloader_BufferDownloaded(XFEDownloader sender, FileDownloadedEventArgs e)
29
{
30
Console.WriteLine($"{e.DownloadedBufferSize.FileSize()} /{((long)e.TotalBufferSize!).FileSize()}");
14
31
}
15
32
}
@@ -1,4 +1,5 @@
1
using System.Diagnostics.CodeAnalysis;
1
using System.Diagnostics;
2
using System.Diagnostics.CodeAnalysis;
2
3
using XFEExtension.NetCore.DelegateExtension;
3
4
using XFEExtension.NetCore.FileExtension;
4
5
using XFEExtension.NetCore.TaskExtension;
@@ -26,7 +27,7 @@ public class XFEDownloader : IDisposable
26
27
/// <summary>
27
28
/// 储存位置
28
29
/// </summary>
29
public string SavePath { get; init; }
30
public required string SavePath { get; init; }
30
31
/// <summary>
31
32
/// 文件分段下载的数量(可加速下载)
32
33
/// </summary>
@@ -35,10 +36,16 @@ public class XFEDownloader : IDisposable
35
36
/// 已下载
36
37
/// </summary>
37
38
public bool Downloaded { get; private set; }
39
private bool isPaused;
38
40
/// <summary>
39
41
/// 暂停
40
42
/// </summary>
41
public bool IsPaused { get; set; }
43
public bool IsPaused
44
{
45
get { return isPaused; }
46
set { isPaused = value; }
47
}
48
42
49
/// <summary>
43
50
/// 开始下载
44
51
/// </summary>
@@ -49,7 +56,7 @@ public class XFEDownloader : IDisposable
49
56
var continueDownload = continueFromLastDownload && File.Exists(SavePath);
50
57
long totalRead = 0;
51
58
var getInfoClient = new HttpClient();
52
responseMessage ??= await GetHttpResponseMessage(getInfoClient);
59
responseMessage ??= await GetHttpResponseMessage(getInfoClient, CancellationToken.None);
53
60
long? totalFileSize = responseMessage.Content.Headers.ContentLength;
54
61
using var createFileStream = new FileStream(SavePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite, 8192, true);
55
62
if (totalFileSize is not null)
@@ -71,13 +78,18 @@ public class XFEDownloader : IDisposable
71
78
httpClient.DefaultRequestHeaders.Range = new System.Net.Http.Headers.RangeHeaderValue(startPosition, endPosition);
72
79
if (continueDownload)
73
80
totalRead += currentSegmentDownloadedBuffeSize;
74
using var contentStream = await (await GetHttpResponseMessage(httpClient)).Content.ReadAsStreamAsync();
81
var cancellationTokenSource = new CancellationTokenSource();
82
var cancellationToken = cancellationTokenSource.Token;
83
using var contentStream = await (await GetHttpResponseMessage(httpClient, cancellationToken)).Content.ReadAsStreamAsync(cancellationToken);
75
84
byte[] buffer = new byte[8192];
76
85
int currentRead;
77
86
while ((currentRead = await contentStream.ReadAsync(buffer)) > 0 && !disposedValue)
78
87
{
79
88
if (IsPaused)
80
while (IsPaused && !disposedValue) { }
89
{
90
await cancellationTokenSource.CancelAsync();
91
break;
92
}
81
93
await fileStream.WriteAsync(buffer.AsMemory(0, currentRead));
82
94
totalRead += currentRead;
83
95
currentSegmentDownloadedBuffeSize += currentRead;
@@ -101,7 +113,12 @@ public class XFEDownloader : IDisposable
101
113
/// 继续下载
102
114
/// </summary>
103
115
/// <returns></returns>
104
public async Task Continue() => await Download();
116
public async Task Continue()
117
{
118
IsPaused = false;
119
await Download();
120
}
121
105
122
/// <summary>
106
123
/// 获取下载信息
107
124
/// </summary>
@@ -109,12 +126,12 @@ public class XFEDownloader : IDisposable
109
126
public async Task<(string? fileName, long? fileSize)> GetDownloadInfo()
110
127
{
111
128
using var httpClient = new HttpClient();
112
responseMessage ??= await GetHttpResponseMessage(httpClient);
129
responseMessage ??= await GetHttpResponseMessage(httpClient, CancellationToken.None);
113
130
return (Path.GetFileName(responseMessage.RequestMessage?.RequestUri?.AbsolutePath), responseMessage.Content.Headers.ContentLength);
114
131
}
115
private async Task<HttpResponseMessage> GetHttpResponseMessage(HttpClient httpClient)
132
private async Task<HttpResponseMessage> GetHttpResponseMessage(HttpClient httpClient, CancellationToken cancellationToken)
116
133
{
117
var response = await httpClient.GetAsync(DownloadUrl, HttpCompletionOption.ResponseHeadersRead);
134
var response = await httpClient.GetAsync(DownloadUrl, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
118
135
response.EnsureSuccessStatusCode();
119
136
return response;
120
137
}
@@ -38,6 +38,8 @@ public interface IObjectInfo
38
38
/// </summary>
39
39
int Layer { get; init; }
40
40
41
string AddObjectPlace();
42
41
43
/// <summary>
42
44
/// 输出对象信息
43
45
/// </summary>
@@ -45,7 +45,7 @@ internal abstract class ObjectInfo : IObjectInfo
45
45
return outPutString;
46
46
}
47
47
48
internal string AddObjectPlace() => ObjectPlace switch
48
public string AddObjectPlace() => ObjectPlace switch
49
49
{
50
50
ObjectPlace.Property => "[属性]",
51
51
ObjectPlace.Field => "[字段]",
@@ -31,7 +31,7 @@ internal abstract class SubObjects(List<IObjectInfo>? objectInfoList) : SubObjec
31
31
else
32
32
{
33
33
outString += $"""
34
├─{Parent.AddObjectPlace()} {XFEConverter.OutPutTypeName(obj.Type)} {obj.Name}
34
├─{obj.AddObjectPlace()} {XFEConverter.OutPutTypeName(obj.Type)} {obj.Name}
35
35
{tabString}├────┬────────────────────────────
36
36
{obj.OutPut()}
37
37
{tabString}{currentConnectString}────────────────────────────────