1
- using System . Diagnostics ;
2
- using System . Runtime . InteropServices ;
3
- using System . Runtime . Versioning ;
4
-
5
- namespace PCL . Neo . Core . Helpers ;
1
+ namespace PCL . Neo . Core . Models ;
6
2
7
3
/// <summary>
8
- /// 一些文件操作和下载请求之类的
4
+ /// 下载任务管理器
5
+ /// 之所以不static是因为后续可能需要接入进度显示和下载统计
9
6
/// </summary>
10
- public static class FileHelper
7
+ public class DownloadService
11
8
{
12
- public static readonly HttpClient HttpClient = new ( ) ;
9
+ /// <summary>
10
+ /// 一个static的HttpClient,以便在任何地方调用
11
+ /// </summary>
12
+ public static HttpClient HttpClient { get ; } = new ( ) ;
13
13
14
14
/// <summary>
15
15
/// 从某个 URL 下载并保存文件
@@ -21,7 +21,7 @@ public static class FileHelper
21
21
/// <param name="maxRetries">最大重试次数</param>
22
22
/// <param name="cancellationToken">用于取消</param>
23
23
/// <returns>向外传递的文件流</returns>
24
- public static async Task < FileStream ? > DownloadFileAsync (
24
+ public async Task < FileStream ? > DownloadFileAsync (
25
25
Uri uri , string localFilePath , string ? sha1 = null , bool passStreamDown = false , int maxRetries = 3 ,
26
26
CancellationToken cancellationToken = default )
27
27
{
@@ -40,6 +40,7 @@ public static class FileHelper
40
40
try
41
41
{
42
42
await response . Content . CopyToAsync ( fileStream , cancellationToken ) ;
43
+ response . EnsureSuccessStatusCode ( ) ;
43
44
if ( ! string . IsNullOrEmpty ( sha1 ) )
44
45
{
45
46
fileStream . Position = 0 ;
@@ -73,82 +74,10 @@ public static class FileHelper
73
74
}
74
75
}
75
76
76
- /// <summary>
77
- /// 校验文件流与SHA-1是否匹配
78
- /// </summary>
79
- /// <param name="fileStream">文件流</param>
80
- /// <param name="sha1">SHA-1</param>
81
- /// <returns>是否匹配</returns>
82
- private static async Task < bool > CheckSha1 ( this FileStream fileStream , string sha1 )
83
- {
84
- using var sha1Provider = System . Security . Cryptography . SHA1 . Create ( ) ;
85
- fileStream . Position = 0 ; // 重置文件流位置
86
- var computedHash = await sha1Provider . ComputeHashAsync ( fileStream ) ;
87
- var computedHashString = Convert . ToHexStringLower ( computedHash ) ;
88
- return string . Equals ( computedHashString , sha1 , StringComparison . OrdinalIgnoreCase ) ;
89
- }
90
-
91
- /// <summary>
92
- /// 在 Unix 系统中给予可执行文件运行权限
93
- /// </summary>
94
- /// <param name="path">文件路径</param>
95
- [ SupportedOSPlatform ( nameof ( OSPlatform . OSX ) ) ]
96
- [ SupportedOSPlatform ( nameof ( OSPlatform . Linux ) ) ]
97
- public static void SetFileExecutableUnix ( this string path )
98
- {
99
- if ( Const . Os is Const . RunningOs . Windows ) return ;
100
- try
101
- {
102
- var currentMode = File . GetUnixFileMode ( path ) ;
103
- var newMode = currentMode | UnixFileMode . UserExecute | UnixFileMode . GroupExecute |
104
- UnixFileMode . OtherExecute ;
105
- File . SetUnixFileMode ( path , newMode ) ;
106
- }
107
- catch ( Exception e )
108
- {
109
- Console . WriteLine ( $ "无法设置可执行权限:{ e . Message } ") ;
110
- throw ;
111
- }
112
- }
113
-
114
- /// <summary>
115
- /// 从某个地方抄来的很像 C 语言风格的解压 LZMA 压缩算法的函数
116
- /// </summary>
117
- /// <param name="inStream">被压缩的文件流</param>
118
- /// <param name="outputFile">输出文件路径</param>
119
- /// <returns>解压后的文件流</returns>
120
- private static FileStream ? DecompressLZMA ( this FileStream inStream , string outputFile )
121
- {
122
- inStream . Position = 0 ;
123
- var outStream = new FileStream ( outputFile , FileMode . Create , FileAccess . ReadWrite ) ;
124
- byte [ ] decodeProperties = new byte [ 5 ] ;
125
- int n = inStream . Read ( decodeProperties , 0 , 5 ) ;
126
- Debug . Assert ( n == 5 ) ;
127
- SevenZip . Compression . LZMA . Decoder decoder = new ( ) ;
128
- decoder . SetDecoderProperties ( decodeProperties ) ;
129
- long outSize = 0 ;
130
- for ( int i = 0 ; i < 8 ; i ++ )
131
- {
132
- int v = inStream . ReadByte ( ) ;
133
- if ( v < 0 )
134
- {
135
- Console . WriteLine ( "read outSize error." ) ;
136
- return null ;
137
- }
138
-
139
- outSize |= ( long ) ( byte ) v << ( 8 * i ) ;
140
- }
141
-
142
- long compressedSize = inStream . Length - inStream . Position ;
143
- decoder . Code ( inStream , outStream , compressedSize , outSize , null ) ;
144
- inStream . Close ( ) ;
145
- return outStream ;
146
- }
147
-
148
77
/// <summary>
149
78
/// 整合函数:下载并解压,然后删去原压缩文件
150
79
/// </summary>
151
- public static async Task DownloadAndDeCompressFileAsync ( Uri uri , string localFilePath , string sha1Raw ,
80
+ public async Task DownloadAndDeCompressFileAsync ( Uri uri , string localFilePath , string sha1Raw ,
152
81
string sha1Lzma , CancellationToken cancellationToken = default )
153
82
{
154
83
var stream = await DownloadFileAsync ( uri , localFilePath + ".lzma" , sha1Lzma , true ,
0 commit comments