in sdk/Common/ResumableDownloadManager.cs [362:445]
private void DownloadPart(object state)
{
DownloadTaskParam taskParam = state as DownloadTaskParam;
if (taskParam == null)
{
throw new ClientException("Internal error. The taskParam should be type of DownloadTaskParam");
}
DownloadObjectRequest request = taskParam.Request;
ResumablePartContext part = taskParam.Part;
EventHandler<StreamTransferProgressArgs> downloadProgressCallback = taskParam.DownloadProgressCallback;
try
{
string fileName = GetTempDownloadFile(request);
if (part.IsCompleted && File.Exists(fileName))
{
// is CRC is enabled and part.Crc64 is 0, then redownload the data
if (!_conf.EnableCrcCheck || part.Crc64 != 0)
{
return;
}
}
const int retryCount = 3;
for (int i = 0; i < retryCount; i++)
{
try
{
GetObjectRequest partRequest = request.ToGetObjectRequest();
partRequest.SetRange(part.Position, part.Position + part.Length - 1);
using(var partResult = _ossClient.GetObject(partRequest))
{
Crc64Stream crcStream = null;
if (_conf.EnableCrcCheck)
{
crcStream = new Crc64Stream(partResult.Content, null, part.Length, 0);
}
using(var fs = File.Open(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
{
fs.Seek(part.Position, SeekOrigin.Begin);
long totalBytes = WriteTo(crcStream ?? partResult.Content, fs);
if (totalBytes != part.Length)
{
throw new OssException(string.Format("Part {0} returns {1} bytes. Expected size is {2} bytes",
part.PartId, totalBytes, part.Length));
}
Interlocked.Add(ref _downloadedBytes, partResult.ContentLength);
}
part.IsCompleted = true;
if (crcStream != null)
{
if (crcStream.CalculatedHash == null)
{
crcStream.CalculateHash();
}
part.Crc64 = BitConverter.ToUInt64(crcStream.CalculatedHash, 0);
}
return;
}
}
catch (Exception ex) // when the connection is closed while sending the data, it will run into ObjectDisposedException.
{
if (!(ex is ObjectDisposedException || ex is WebException) || i == retryCount - 1)
{
throw;
}
}
}
throw new ClientException("DownloadPart runs into internal error");
}
catch(Exception e)
{
taskParam.Error = e;
}
finally
{
taskParam.DownloadFinished.Set();
}
}