Skip to content

Commit b70b9a0

Browse files
committed
修复记录下载的文件没有返回
1 parent 976f8b0 commit b70b9a0

7 files changed

Lines changed: 384 additions & 95 deletions

src/FileDownloader.Tests/BreakpointResumptionTransmissionManagerTest.cs

Lines changed: 320 additions & 58 deletions
Large diffs are not rendered by default.

src/FileDownloader.Tests/BreakpointResumptionTransmissionRecordFileFormatterTest.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public void Format()
4040
Assert.IsNotNull(result);
4141

4242
Assert.AreEqual(downloadLength, result.DownloadLength);
43+
Assert.IsNotNull(result.DownloadedInfo);
4344
Assert.AreEqual(downloadedInfo.Count, result.DownloadedInfo.Count);
4445

4546
for (int i = 0; i < downloadedInfo.Count; i++)

src/dotnetCampus.FileDownloader/DownloadSegment.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,19 @@ public DownloadSegment(long startPoint, long requirementDownloadPoint)
4848
/// 当前的信息,仅用于调试
4949
/// </summary>
5050
public string? Message { get; set; }
51+
52+
/// <summary>
53+
/// 最后的下载状态更新时间
54+
/// </summary>
55+
/// todo 改名 LastDownloadTime 或 LastUpdateTime
5156
public DateTime LastDownTime { get; set; } = DateTime.Now;
57+
58+
/// <summary>
59+
/// 下载状态
60+
/// </summary>
61+
/// todo 改名 DownloadingState
5262
public DownloadingState LoadingState { get; set; } = DownloadingState.Pause;
63+
5364
/// <summary>
5465
/// 需要下载到的点
5566
/// </summary>
@@ -98,13 +109,24 @@ internal set
98109
/// </summary>
99110
public SegmentManager? SegmentManager { set; get; }
100111
}
112+
101113
/// <summary>
102114
/// 下载状态
103115
/// </summary>
104116
public enum DownloadingState
105117
{
118+
/// <summary>
119+
/// 运行中
120+
/// </summary>
121+
/// todo 改名 Running
106122
Runing = 1,
123+
/// <summary>
124+
/// 暂停
125+
/// </summary>
107126
Pause = 0,
127+
/// <summary>
128+
/// 完成
129+
/// </summary>
108130
Finished = -1
109131
}
110132
}

src/dotnetCampus.FileDownloader/Utils/BreakpointResumptionTransmissions/BreakpointResumptionTransmissionManager.Crc32.cs renamed to src/dotnetCampus.FileDownloader/Utils/BreakpointResumptionTransmissions/BreakpointResumptionTransmissionManager.Crc64.cs

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,30 @@
66
namespace dotnetCampus.FileDownloader.Utils.BreakpointResumptionTransmissions;
77
internal partial class BreakpointResumptionTransmissionManager
88
{
9-
// Copy From dotnet runtime: \src\libraries\System.IO.Hashing\src\System\IO\Hashing\Crc32.cs
9+
// Copy From dotnet runtime: \src\libraries\System.IO.Hashing\src\System\IO\Hashing\Crc64.cs
1010
// Licensed to the .NET Foundation under one or more agreements.
1111
// The .NET Foundation licenses this file to you under the MIT license.
12-
class Crc32
12+
class Crc64
1313
{
14-
private const uint InitialState = 0xFFFF_FFFFu;
15-
private const int Size = sizeof(uint);
14+
private const ulong InitialState = 0UL;
15+
private const int Size = sizeof(ulong);
1616

17-
private uint _crc = InitialState;
17+
private ulong _crc = InitialState;
1818

1919
/// <summary>
20-
/// Initializes a new instance of the <see cref="Crc32"/> class.
20+
/// Initializes a new instance of the <see cref="Crc64"/> class.
2121
/// </summary>
22-
public Crc32()
22+
public Crc64()
2323
{
24-
_crcLookup = GenerateReflectedTable(0xEDB88320u);
24+
_crcLookup = GenerateTable(0x42F0E1EBA9EA3693);
2525
}
2626

2727
/// <summary>
2828
/// Appends the contents of <paramref name="source"/> to the data already
2929
/// processed for the current hash computation.
3030
/// </summary>
3131
/// <param name="source">The data to process.</param>
32-
public uint Append(ReadOnlySpan<byte> source)
32+
public ulong Append(ReadOnlySpan<byte> source)
3333
{
3434
_crc = Update(_crc, source);
3535
return _crc;
@@ -51,7 +51,7 @@ public void Reset()
5151
protected void GetCurrentHashCore(Span<byte> destination)
5252
{
5353
// The finalization step of the CRC is to perform the ones' complement.
54-
BinaryPrimitives.WriteUInt32LittleEndian(destination, ~_crc);
54+
BinaryPrimitives.WriteUInt64BigEndian(destination, _crc);
5555
}
5656

5757
/// <summary>
@@ -60,7 +60,7 @@ protected void GetCurrentHashCore(Span<byte> destination)
6060
/// </summary>
6161
protected void GetHashAndResetCore(Span<byte> destination)
6262
{
63-
BinaryPrimitives.WriteUInt32LittleEndian(destination, ~_crc);
63+
BinaryPrimitives.WriteUInt64BigEndian(destination, _crc);
6464
_crc = InitialState;
6565
}
6666

@@ -134,19 +134,19 @@ public int Hash(ReadOnlySpan<byte> source, Span<byte> destination)
134134

135135
private int StaticHash(ReadOnlySpan<byte> source, Span<byte> destination)
136136
{
137-
uint crc = InitialState;
137+
ulong crc = InitialState;
138138
crc = Update(crc, source);
139-
BinaryPrimitives.WriteUInt32LittleEndian(destination, ~crc);
139+
BinaryPrimitives.WriteUInt64BigEndian(destination, crc);
140140
return Size;
141141
}
142142

143-
private uint Update(uint crc, ReadOnlySpan<byte> source)
143+
private ulong Update(ulong crc, ReadOnlySpan<byte> source)
144144
{
145145
for (int i = 0; i < source.Length; i++)
146146
{
147-
byte idx = (byte) crc;
147+
ulong idx = (crc >> 56);
148148
idx ^= source[i];
149-
crc = _crcLookup[idx] ^ (crc >> 8);
149+
crc = _crcLookup[idx] ^ (crc << 8);
150150
}
151151

152152
return crc;
@@ -156,25 +156,25 @@ private uint Update(uint crc, ReadOnlySpan<byte> source)
156156
// While this implementation is based on the standard CRC-32 polynomial,
157157
// x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x1 + x0,
158158
// this version uses reflected bit ordering, so 0x04C11DB7 becomes 0xEDB88320
159-
private readonly uint[] _crcLookup;
159+
private readonly ulong[] _crcLookup;
160160

161-
private static uint[] GenerateReflectedTable(uint reflectedPolynomial)
161+
private static ulong[] GenerateTable(ulong polynomial)
162162
{
163-
uint[] table = new uint[256];
163+
ulong[] table = new ulong[256];
164164

165165
for (int i = 0; i < 256; i++)
166166
{
167-
uint val = (uint) i;
167+
ulong val = (ulong) i << 56;
168168

169169
for (int j = 0; j < 8; j++)
170170
{
171-
if ((val & 0b0000_0001) == 0)
171+
if ((val & 0x8000_0000_0000_0000) == 0)
172172
{
173-
val >>= 1;
173+
val <<= 1;
174174
}
175175
else
176176
{
177-
val = (val >> 1) ^ reflectedPolynomial;
177+
val = (val << 1) ^ polynomial;
178178
}
179179
}
180180

src/dotnetCampus.FileDownloader/Utils/BreakpointResumptionTransmissions/BreakpointResumptionTransmissionManager.cs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ public async Task<SegmentManager> CreateSegmentManagerAsync(FileStream downloadF
9393
item.SegmentManager = segmentManager;
9494
item.Number = i;
9595
}
96+
97+
return segmentManager;
9698
}
9799
else
98100
{
@@ -103,8 +105,6 @@ public async Task<SegmentManager> CreateSegmentManagerAsync(FileStream downloadF
103105
Formatter.Write(BinaryWriter, new BreakpointResumptionTransmissionInfo(DownloadLength));
104106
return new SegmentManager(DownloadLength);
105107
}
106-
107-
return new SegmentManager(DownloadLength);
108108
}
109109

110110
/// <summary>
@@ -113,7 +113,7 @@ public async Task<SegmentManager> CreateSegmentManagerAsync(FileStream downloadF
113113
/// <param name="downloadedInfo"></param>
114114
/// <param name="downloadFileStream"></param>
115115
/// <returns></returns>
116-
internal List<DownloadSegment> GetDownloadSegmentList(List<DataRange> downloadedInfo, FileStream downloadFileStream)
116+
private List<DownloadSegment> GetDownloadSegmentList(List<DataRange> downloadedInfo, FileStream downloadFileStream)
117117
{
118118
downloadedInfo.Sort(new DataRangeComparer());
119119
var list = downloadedInfo;
@@ -152,8 +152,8 @@ bool IsDownloaded()
152152
var buffer = SharedArrayPool.Rent(BufferLength);
153153
try
154154
{
155-
var crc32 = new Crc32();
156-
uint checksum = 0;
155+
var crc64 = new Crc64();
156+
ulong checksum = 0;
157157
var remainLength = current.Length;
158158
while (remainLength > 0)
159159
{
@@ -164,7 +164,7 @@ bool IsDownloaded()
164164
return false;
165165
}
166166

167-
checksum = crc32.Append(buffer.AsSpan(0, read));
167+
checksum = crc64.Append(buffer.AsSpan(0, read));
168168
remainLength -= readLength;
169169
}
170170

@@ -181,7 +181,8 @@ bool IsDownloaded()
181181

182182
var currentDownloadSegment = new DownloadSegment(current.StartPoint, current.StartPoint + current.Length)
183183
{
184-
DownloadedLength = current.Length,
184+
// 已经下载的长度。如果校验下载失败,则长度是 0 否则为记录的长度
185+
DownloadedLength = isDownloaded ? current.Length : 0,
185186
LoadingState = isDownloaded ? DownloadingState.Finished : DownloadingState.Pause,
186187
};
187188
downloadSegmentList.Add(currentDownloadSegment);
@@ -253,7 +254,7 @@ private void RecordDownloaded(StepWriteFinishedArgs args)
253254
throw new InvalidOperationException("必须在调用 CreateSegmentManagerAsync 完成之后才能进入 RecordDownloaded 方法");
254255
}
255256

256-
var crc32 = new Crc32();
257+
var crc32 = new Crc64();
257258
var checksum = crc32.Append(args.Data.AsSpan(args.DataOffset, args.DataLength));
258259

259260
Formatter.AppendDataRange(BinaryWriter, new DataRange(args.FileStartPoint, args.DataLength, checksum));

src/dotnetCampus.FileDownloader/Utils/BreakpointResumptionTransmissions/BreakpointResumptionTransmissionRecordFileFormatter.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,24 @@ class BreakpointResumptionTransmissionRecordFileFormatter
2525
return null;
2626
}
2727

28-
// 预期在 Header 之后是下载文件的长度
28+
// 预期在 Header 之后是下载文件的长度。下载文件的长度包含两个部分内容:1. 文件长度标识(DataType.DownloadFileLength) 2. 文件长度
29+
// 读取文件长度标识
2930
(success, data) = await ReadInner();
3031
if (!success || data != (long) DataType.DownloadFileLength)
3132
{
32-
// 证明文件组织形式错误了,没有读取到下载文件的长度
33+
// 证明文件组织形式错误了,没有读取到下载文件的长度的标识
3334
return null;
3435
}
3536

3637
// 获取需要下载的文件长度
3738
(success, data) = await ReadInner();
3839
if (!success)
3940
{
40-
// 没有读取到下载的文件长度,返回空即可
41+
// 没有读取到下载的文件长度,返回空即可,证明此记录内容不正确
4142
return null;
4243
}
44+
45+
// 文件长度之后的内容是分块下载的内容。分块下载的内容是一个个的 DataRange 结构体
4346
var downloadLength = data;
4447

4548
List<DataRange> downloadedInfo = new();
@@ -88,7 +91,7 @@ class BreakpointResumptionTransmissionRecordFileFormatter
8891
// 数据错误,没有记录全一条信息,重新建立记录文件
8992
break;
9093
}
91-
var checksum = data;
94+
var checksum = (ulong) data;
9295

9396
downloadedInfo.Add(new DataRange(startPoint, length, checksum));
9497
}

src/dotnetCampus.FileDownloader/Utils/BreakpointResumptionTransmissions/DataRange.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace dotnetCampus.FileDownloader.Utils.BreakpointResumptionTransmissions;
55

66
readonly struct DataRange : IComparer<DataRange>, IEquatable<DataRange>
77
{
8-
public DataRange(long startPoint, long length, long checksum)
8+
public DataRange(long startPoint, long length, ulong checksum)
99
{
1010
StartPoint = startPoint;
1111
Length = length;
@@ -16,7 +16,7 @@ public DataRange(long startPoint, long length, long checksum)
1616

1717
public long Length { get; }
1818

19-
public long Checksum { get; }
19+
public ulong Checksum { get; }
2020

2121
public long LastPoint => StartPoint + Length;
2222

0 commit comments

Comments
 (0)