123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878 |
- using System;
- using System.Collections.Concurrent;
- using System.Collections.Generic;
- using System.IO;
- using System.Net.Http;
- using System.Net.Http.Headers;
- using Vinno.vCloud.Common.Storage.ObjectStorageInfo.Solid;
- using Vinno.IUS.Common.Log;
- using System.Threading;
- namespace Vinno.vCloud.Common.Storage.ObjectStorageInfo
- {
- public class ObjectStorage : IObjectStorage
- {
- public ObjectStorage(ObjectUserAgent objectUserAgent)
- {
- _objectUserAgent = objectUserAgent;
- }
- private ObjectUserAgent _objectUserAgent = null;
- private const int chunkSize = 2097152;//2M;
- /// <summary>
- /// 上传文件(字节流)
- /// </summary>
- /// <param name="filePath"></param>
- /// <param name="fileName"></param>
- /// <param name="progressCallback"></param>
- /// <returns></returns>
- public bool UploadFile(byte[] fileData, MediaTypeHeaderValue mediaTypeHeaderValue, string requestUrl, Dictionary<string, string> heads, ProductInfoHeaderValue productInfoHeader, Action<double> progressCallback = null, CancellationTokenSource cancelTokenSource = null)
- {
- if (fileData == null || fileData.Length == 0)
- {
- throw new Exception("FileData is empty");
- }
- if (_objectUserAgent == null)
- {
- throw new Exception("UFileConfig not set");
- }
- long allStreamLength = 0;
- using (var requestHead = new HttpRequestMessage())
- {
- try
- {
- requestHead.RequestUri = new Uri(requestUrl);
- requestHead.Method = HttpMethod.Head;
- allStreamLength = HttpClientHelper.ExecuteRequest(requestHead, HttpClientHelper.GetLengthResult,false, cancelTokenSource);
- if (fileData.Length == allStreamLength)
- {
- return true;
- }
- }
- catch (Exception ex)
- {
- Logger.WriteLineError($"Get file head error {ex}");
- }
- }
- using (var request = new HttpRequestMessage())
- {
- using (var content = new UploadContent(fileData, mediaTypeHeaderValue))
- {
- content.ProgressChanged += (sender, progress) => { progressCallback?.Invoke(progress); };
- request.RequestUri = new Uri(requestUrl);
- request.Method = HttpMethod.Put;
- request.Content = content;
- if (productInfoHeader != null)
- {
- request.Headers.UserAgent.Add(productInfoHeader);
- }
- foreach (var head in heads)
- {
- request.Headers.TryAddWithoutValidation(head.Key, head.Value);
- }
- return HttpClientHelper.ExecuteRequest(request, HttpClientHelper.GetBooleanResult,false,cancelTokenSource);
- }
- }
- }
- /// <summary>
- /// 复制文件
- /// </summary>
- /// <param name="destinationUrl">目标服务器</param>
- /// <param name="sourceFileUrl">源服务器</param>
- /// <param name="heads">签名</param>
- /// <returns>是否成功</returns>
- public bool CopyFile(string destinationUrl,string sourceFileUrl, Dictionary<string, string> heads)
- {
- var res = false;
- using (var request = new HttpRequestMessage())
- {
- request.RequestUri = new Uri(destinationUrl);
- request.Method = HttpMethod.Put;
- request.Headers.TryAddWithoutValidation("x-cos-copy-source", sourceFileUrl);
- foreach (var head in heads)
- {
- request.Headers.TryAddWithoutValidation(head.Key, head.Value);
- }
- res = HttpClientHelper.ExecuteRequest(request);
- }
- return res;
- }
- /// <summary>
- /// 上传文件
- /// </summary>
- /// <param name="filePath"></param>
- /// <param name="fileName"></param>
- /// <param name="progressCallback"></param>
- /// <returns></returns>
- public bool UploadFile(string filePath, string mimeType, string requestUrl, Dictionary<string, string> heads, ProductInfoHeaderValue productInfoHeader, Action<double> progressCallback = null)
- {
- if (string.IsNullOrWhiteSpace(filePath))
- {
- Logger.WriteLineError("filePath can't be empty");
- return false;
- }
- if (string.IsNullOrWhiteSpace(requestUrl))
- {
- Logger.WriteLineError("requestUrl can't be empty");
- return false;
- }
- if (_objectUserAgent == null)
- {
- throw new Exception("UFileConfig not set");
- }
- long allStreamLength = 0;
- using (var requestHead = new HttpRequestMessage())
- {
- try
- {
- requestHead.RequestUri = new Uri(requestUrl);
- requestHead.Method = HttpMethod.Head;
- allStreamLength = HttpClientHelper.ExecuteRequest(requestHead, HttpClientHelper.GetLengthResult);
- }
- catch (Exception ex)
- {
- Logger.WriteLineError($"Get file head error {ex}");
- }
- }
- using (var request = new HttpRequestMessage())
- {
- using (var content = new UploadContent(filePath))
- {
- try
- {
- if (content.CompareFileSizes(allStreamLength))
- {
- return true;
- }
- content.ProgressChanged += (sender, progress) => { progressCallback?.Invoke(progress); };
- content.Headers.ContentType = MediaTypeHeaderValue.Parse(mimeType);
- request.RequestUri = new Uri(requestUrl);
- request.Method = HttpMethod.Put;
- request.Content = content;
- if (productInfoHeader != null)
- {
- request.Headers.UserAgent.Add(productInfoHeader);
- }
- foreach (var head in heads)
- {
- request.Headers.TryAddWithoutValidation(head.Key, head.Value);
- }
- return HttpClientHelper.ExecuteRequest(request, HttpClientHelper.GetBooleanResult);
- }
- catch (Exception ex)
- {
- Logger.WriteLineError($"{ex}");
- return false;
- }
- finally
- {
- content.Dispose();
- }
- }
- }
- }
- /// <summary>
- /// 批量上传文件
- /// </summary>
- /// <param name="uFileInfos"></param>
- /// <param name="progressCallback"></param>
- /// <returns></returns>
- public bool UploadFiles(List<ObjectFileInfo> uFileInfos, Dictionary<string, string> heads, ProductInfoHeaderValue productInfoHeader)
- {
- if (_objectUserAgent == null)
- {
- throw new Exception("UFileConfig not set");
- }
- ConcurrentQueue<QueueRequestEntity> httpRequestMessageQueue = new ConcurrentQueue<QueueRequestEntity>();
- int queueIndex = 1;
- foreach (var file in uFileInfos)
- {
- if (file != null && File.Exists(file.FilePath))
- {
- long allStreamLength = 0;
- using (var requestHead = new HttpRequestMessage())
- {
- try
- {
- requestHead.RequestUri = new Uri(file.RequestUrl);
- requestHead.Method = HttpMethod.Head;
- allStreamLength = HttpClientHelper.ExecuteRequest(requestHead, HttpClientHelper.GetLengthResult);
- file.FileLength = allStreamLength;
- }
- catch (Exception ex)
- {
- Logger.WriteLineError($"Get file head error {ex}");
- }
- }
- var request = new HttpRequestMessage();
- request.RequestUri = new Uri(file.RequestUrl);
- request.Method = HttpMethod.Put;
- if (productInfoHeader != null)
- {
- request.Headers.UserAgent.Add(productInfoHeader);
- }
- foreach (var head in heads)
- {
- request.Headers.TryAddWithoutValidation(head.Key, head.Value);
- }
- request.Headers.Add("Authorization", file.Authorization);
- httpRequestMessageQueue.Enqueue(new QueueRequestEntity
- {
- FileInfo = file,
- QueueCount = uFileInfos.Count,
- QueueIndex = queueIndex,
- Request = request,
- CompleteWorker = UploadFileCallback
- });
- queueIndex++;
- }
- }
- var result = HttpClientHelper.ExecuteRequestQueue(httpRequestMessageQueue);
- return result;
- }
- /// <summary>
- /// 上传文件回调
- /// </summary>
- /// <param name="queueWorkItem"></param>
- private void UploadFileCallback(QueueWorkItem queueWorkItem)
- {
- queueWorkItem.ProgressCallback?.Invoke((int)(100.0 * queueWorkItem.QueueIndex / queueWorkItem.QueueCount));
- }
- /// <summary>
- /// 获取文件
- /// </summary>
- /// <param name="requestUrl">请求地址</param>
- /// <param name="from">Range开始位置</param>
- /// <param name="to">Range结束位置</param>
- /// <param name="progressCallback"></param>
- /// <returns></returns>
- public byte[] GetFile(string requestUrl, long from, long to, Action<double> progressCallback = null)
- {
- if (string.IsNullOrWhiteSpace(requestUrl))
- {
- Logger.WriteLineError("requestUrl can't be empty");
- return new byte[0];
- }
- if (_objectUserAgent == null)
- {
- throw new Exception("UFileConfig not set");
- }
- using (var request = new HttpRequestMessage())
- {
- request.RequestUri = new Uri(requestUrl);
- request.Method = HttpMethod.Head;
- long allStreamLength = HttpClientHelper.ExecuteRequest(request, HttpClientHelper.GetLengthResult);
- using (var memoryStream = new MemoryStream())
- {
- if (Downloading(requestUrl, null, memoryStream, allStreamLength, from, to, true, progressCallback))
- {
- return memoryStream.ToArray();
- }
- return new byte[0];
- }
- }
- }
- /// <summary>
- /// 获取文件
- /// </summary>
- /// <param name="requestUrl"></param>
- /// <param name="progressCallback"></param>
- /// <returns></returns>
- public byte[] GetFile(string requestUrl, Action<double> progressCallback = null)
- {
- // Logger.WriteLineInfo($"ObjectStroage Get file buffer with file token:{requestUrl}");
- if (string.IsNullOrWhiteSpace(requestUrl))
- {
- Logger.WriteLineError("requestUrl can't be empty");
- return new byte[0];
- }
- if (_objectUserAgent == null)
- {
- throw new Exception("UFileConfig not set");
- }
- using (var request = new HttpRequestMessage())
- {
- request.RequestUri = new Uri(requestUrl);
- request.Method = HttpMethod.Head;
- long allStreamLength = HttpClientHelper.ExecuteRequest(request, HttpClientHelper.GetLengthResult);
- using (var memoryStream = new MemoryStream())
- {
- if (Downloading(requestUrl, null, memoryStream, allStreamLength, -1, -1, true, progressCallback))
- {
- // Logger.WriteLineInfo($"Downloading success with file token:{requestUrl}");
- return memoryStream.ToArray();
- }
- // Logger.WriteLineInfo($"Downloading done with file token:{requestUrl}");
- return new byte[0];
- }
- }
- }
- /// <summary>
- /// 下载文件
- /// </summary>
- /// <param name="filePath">文件路径</param>
- /// <param name="requestUrl">请求地址</param>
- /// <param name="from">Range开始位置</param>
- /// <param name="to">Range结束位置</param>
- /// <param name="progressCallback"></param>
- /// <returns></returns>
- public bool DownloadFile(string filePath, string requestUrl, long from, long to, Action<double> progressCallback = null)
- {
- if (string.IsNullOrWhiteSpace(filePath))
- {
- Logger.WriteLineError("filePath can't be empty");
- return false;
- }
- if (string.IsNullOrWhiteSpace(requestUrl))
- {
- Logger.WriteLineError("requestUrl can't be empty");
- return false;
- }
- if (_objectUserAgent == null)
- {
- throw new Exception("UFileConfig not set");
- }
- if (string.IsNullOrWhiteSpace(filePath))
- {
- throw new Exception("File path is empty");
- }
- using (var request = new HttpRequestMessage())
- {
- request.RequestUri = new Uri(requestUrl);
- request.Method = HttpMethod.Head;
- long allStreamLength = HttpClientHelper.ExecuteRequest(request, HttpClientHelper.GetLengthResult);
- Directory.CreateDirectory(Path.GetDirectoryName(filePath));
- FileMode fileMode = FileMode.CreateNew;
- if (File.Exists(filePath))
- {
- var fileInfo = new FileInfo(filePath);
- if ((DateTime.UtcNow - fileInfo.LastWriteTimeUtc).Hours <= 1)
- {
- progressCallback?.Invoke(1.0);
- return true;
- }
- else
- {
- File.Delete(filePath);
- }
- }
- var tempFile = filePath + ".tmp";
- if (File.Exists(tempFile))
- {
- var fileInfo = new FileInfo(tempFile);
- if ((DateTime.UtcNow - fileInfo.LastWriteTimeUtc).Hours <= 1)
- {
- fileMode = FileMode.OpenOrCreate;
- }
- else
- {
- File.Delete(tempFile);
- }
- }
- using (var fileStream = new FileStream(tempFile, fileMode, FileAccess.ReadWrite, FileShare.ReadWrite))
- {
- if (allStreamLength == 0)
- {
- return false;
- }
- if (fileStream.Length == allStreamLength)
- {
- progressCallback?.Invoke(100);
- return true;
- }
- return Downloading(requestUrl, filePath, fileStream, allStreamLength, from, to, true, progressCallback);
- }
- }
- }
- /// <summary>
- /// 下载文件
- /// </summary>
- /// <param name="fileName"></param>
- /// <param name="filePath"></param>
- /// <param name="progressCallback"></param>
- /// <returns></returns>
- public bool DownloadFile(string filePath, string requestUrl, Action<double> progressCallback = null,CancellationTokenSource cancelTokenSource = null)
- {
- if (string.IsNullOrWhiteSpace(filePath))
- {
- Logger.WriteLineError("filePath can't be empty");
- return false;
- }
- if (string.IsNullOrWhiteSpace(requestUrl))
- {
- Logger.WriteLineError("requestUrl can't be empty");
- return false;
- }
- if (_objectUserAgent == null)
- {
- throw new Exception("UFileConfig not set");
- }
- if (string.IsNullOrWhiteSpace(filePath))
- {
- throw new Exception("File path is empty");
- }
- using (var request = new HttpRequestMessage())
- {
- request.RequestUri = new Uri(requestUrl);
- request.Method = HttpMethod.Head;
- long allStreamLength = HttpClientHelper.ExecuteRequest(request, HttpClientHelper.GetLengthResult);
- Directory.CreateDirectory(Path.GetDirectoryName(filePath));
- FileMode fileMode = FileMode.CreateNew;
- if (File.Exists(filePath))
- {
- var fileInfo = new FileInfo(filePath);
- if (fileInfo.Length == allStreamLength && (DateTime.UtcNow - fileInfo.LastWriteTimeUtc).Hours <= 1)
- {
- progressCallback?.Invoke(1.0);
- return true;
- }
- else
- {
- File.Delete(filePath);
- }
- }
- var tempFile = filePath + ".tmp";
- if (File.Exists(tempFile))
- {
- Logger.WriteLineInfo($"Delete the temp file when the temp file {tempFile} already exist");
- File.Delete(tempFile);
- }
- if (allStreamLength == 0)
- {
- Logger.WriteLineWarn($"file length is empty, token:{requestUrl}");
- return false;
- }
- var result = false;
- using (var fileStream = new FileStream(tempFile, fileMode, FileAccess.ReadWrite, FileShare.ReadWrite))
- {
- result = Downloading(requestUrl, filePath, fileStream, allStreamLength, -1, -1, true, progressCallback, cancelTokenSource);
- if (!result)
- {
- fileStream.Dispose();
- }
- }
- if (!result && File.Exists(tempFile))
- {
- Logger.WriteLineInfo($"Delete the temp file when failed {tempFile}");
- File.Delete(tempFile);
- }
- return result;
- }
- }
- /// <summary>
- /// 批量下载文件
- /// </summary>
- /// <param name="uFileInfos"></param>
- /// <param name="progressCallback"></param>
- /// <returns></returns>
- public bool DownloadFiles(List<ObjectFileInfo> uFileInfos, Action<double> progressCallback = null)
- {
- if (_objectUserAgent == null)
- {
- throw new Exception("UFileConfig not set");
- }
- ConcurrentQueue<QueueRequestEntity> httpRequestMessageQueue = new ConcurrentQueue<QueueRequestEntity>();
- int queueIndex = 1;
- foreach (var file in uFileInfos)
- {
- var request = new HttpRequestMessage();
- request.RequestUri = new Uri(file.RequestUrl);
- request.Method = HttpMethod.Head;
- httpRequestMessageQueue.Enqueue(new QueueRequestEntity
- {
- FileInfo = file,
- QueueCount = uFileInfos.Count,
- QueueIndex = queueIndex,
- ProgressCallback = progressCallback,
- Request = request,
- CompleteWorker = DownloadFileCallback
- });
- queueIndex++;
- }
- var result = HttpClientHelper.ExecuteRequestQueue(httpRequestMessageQueue);
- return result;
- }
- /// <summary>
- /// 下载文件回调
- /// </summary>
- /// <param name="queueWorkItem"></param>
- private void DownloadFileCallback(QueueWorkItem queueWorkItem)
- {
- if (queueWorkItem.Response == null)
- {
- return;
- }
- long allStreamLength = HttpClientHelper.GetLengthResult(queueWorkItem.Response);
- var FileDirectory = Path.GetDirectoryName(queueWorkItem.FileInfo.FilePath);
- if (!Directory.Exists(FileDirectory))
- {
- Directory.CreateDirectory(FileDirectory);
- }
- FileMode fileMode = FileMode.CreateNew;
- if (File.Exists(queueWorkItem.FileInfo.FilePath))
- {
- var fileInfo = new FileInfo(queueWorkItem.FileInfo.FilePath);
- if (fileInfo.Length == allStreamLength && (DateTime.UtcNow - fileInfo.LastWriteTimeUtc).Hours <= 1)
- {
- queueWorkItem.ProgressCallback?.Invoke((int)(100.0 * queueWorkItem.QueueIndex / queueWorkItem.QueueCount));
- return;
- }
- else
- {
- File.Delete(queueWorkItem.FileInfo.FilePath);
- }
- }
- var tempFile = queueWorkItem.FileInfo.FilePath + ".tmp";
- if (File.Exists(tempFile))
- {
- var fileInfo = new FileInfo(tempFile);
- if ((DateTime.UtcNow - fileInfo.LastWriteTimeUtc).Hours <= 1)
- {
- fileMode = FileMode.OpenOrCreate;
- }
- else
- {
- File.Delete(tempFile);
- }
- }
- using (var fileStream = new FileStream(tempFile, fileMode, FileAccess.ReadWrite, FileShare.ReadWrite))
- {
- if (fileStream.Length == allStreamLength)
- {
- queueWorkItem.ProgressCallback?.Invoke((int)(100.0 * queueWorkItem.QueueIndex / queueWorkItem.QueueCount));
- return;
- }
- if (Downloading(queueWorkItem.FileInfo.RequestUrl, queueWorkItem.FileInfo.FilePath, fileStream, allStreamLength))
- {
- queueWorkItem.ProgressCallback?.Invoke((int)(100.0 * queueWorkItem.QueueIndex / queueWorkItem.QueueCount));
- return;
- }
- else
- {
- if (HttpClientHelper.IsFinalAgreement)
- {
- throw new Exception("Download fail");
- }
- }
- }
- }
- /// <summary>
- /// 下载逻辑
- /// </summary>
- /// <param name="requestUrl"></param>
- /// <param name="filePath"></param>
- /// <param name="fileStream"></param>
- /// <param name="fileSize"></param>
- /// <param name="from"></param>
- /// <param name="to"></param>
- /// <param name="isKeepAlive"></param>
- /// <param name="progressCallback"></param>
- /// <returns></returns>
- private bool Downloading(string requestUrl, string filePath, Stream fileStream, long fileSize, long from = -1, long to = -1, bool isKeepAlive = false, Action<double> progressCallback = null, CancellationTokenSource cancelTokenSource = null)
- {
- bool isDownloadSuccess = false;
- if (fileStream == null)
- {
- Logger.WriteLineError("fileStream can't be null");
- return false;
- }
- if (string.IsNullOrWhiteSpace(filePath) && !(fileStream is MemoryStream))
- {
- Logger.WriteLineError("filePath can't be empty");
- return false;
- }
- if (string.IsNullOrWhiteSpace(requestUrl))
- {
- Logger.WriteLineError("requestUrl can't be empty");
- return false;
- }
- try
- {
- if (from == -1 && to == -1)
- {
- fileStream.Seek(fileStream.Length, SeekOrigin.Current);
- for (int fileIndex = (int)fileStream.Length; true; fileIndex += chunkSize)
- {
- if (fileStream.Length >= fileSize)
- {
- break;
- }
- var newLength = GetNewLength(fileStream.Length, chunkSize, fileSize);
- if (!DoHttpRequest(requestUrl, fileStream, fileStream.Length, newLength, fileIndex, fileSize, isKeepAlive, progressCallback,cancelTokenSource))
- {
- if (cancelTokenSource != null && cancelTokenSource.IsCancellationRequested)
- {
- Logger.WriteLineError($"Download failed {filePath} with code position 1");
- return false;
- }
- break;
- }
- }
- }
- else
- {
- int tryCount = 0;
- do
- {
- if (!DoHttpRequest(requestUrl, fileStream, from, to, fileSize, fileSize, isKeepAlive, progressCallback,cancelTokenSource))
- {
- if (cancelTokenSource != null && cancelTokenSource.IsCancellationRequested)
- {
- Logger.WriteLineError($"Download failed {filePath} with code position 2");
- return false;
- }
- tryCount++;
- }
- else
- {
- if (cancelTokenSource != null && cancelTokenSource.IsCancellationRequested)
- {
- Logger.WriteLineError($"Download failed {filePath} with code position 3");
- return false;
- }
- break;
- }
- }
- while (tryCount < 2);
- }
- if (fileStream.Length == fileSize)
- {
- isDownloadSuccess = true;
- progressCallback?.Invoke(1.0);
- if (!string.IsNullOrWhiteSpace(filePath))
- {
- fileStream.Close();
- File.Move(filePath + ".tmp", filePath);
- // Logger.WriteLineInfo($"download success, file token:{requestUrl}");
- }
- }
- else {
- Logger.WriteLineError($"Download failed since file stream length not equal with filesize" +
- $"the stream length is {fileStream?.Length}, the file size is {fileSize}");
- }
- }
- catch (Exception ex)
- {
- if (!HttpClientHelper.IsFinalAgreement)
- {
- Logger.WriteLineError($"Downloding ufile error {ex}");
- }
- else
- {
- Logger.WriteLineError($"Throw the downloading exception {ex}");
- throw ex;
- }
- }
- finally
- {
- fileStream.Close();
- }
- return isDownloadSuccess;
- }
- /// <summary>
- /// 下载http请求
- /// </summary>
- /// <param name="requestUrl"></param>
- /// <param name="fileStream"></param>
- /// <param name="rangeFrom"></param>
- /// <param name="rangeTo"></param>
- /// <param name="fileSize"></param>
- /// <param name="isKeepAlive"></param>
- /// <param name="progressCallback"></param>
- /// <returns></returns>
- private bool DoHttpRequest(string requestUrl, Stream fileStream, long rangeFrom, long rangeTo, long fileIndex, long fileSize, bool isKeepAlive, Action<double> progressCallback, CancellationTokenSource cancelTokenSource = null)
- {
- if (fileStream == null)
- {
- Logger.WriteLineError("fileStream can't be null");
- return false;
- }
- if (string.IsNullOrWhiteSpace(requestUrl))
- {
- Logger.WriteLineError("requestUrl can't be empty");
- return false;
- }
- try
- {
- using (var downloadRequest = new HttpRequestMessage())
- {
- downloadRequest.RequestUri = new Uri(requestUrl);
- downloadRequest.Method = HttpMethod.Get;
- if (rangeTo > fileSize)
- {
- rangeTo = fileSize;
- }
- downloadRequest.Headers.Range = new RangeHeaderValue(rangeFrom, rangeTo);
- using (var downloadStream = HttpClientHelper.ExecuteRequest(downloadRequest, HttpClientHelper.GetStreamResult, isKeepAlive,cancelTokenSource))
- {
- if (downloadStream == null)
- {
- return false;
- }
- var readLength = rangeTo - rangeFrom;
- var dataToWrite = new byte[readLength];
- var downloadLength = downloadStream.Read(dataToWrite, 0, (int)readLength);
- fileStream.Write(dataToWrite, 0, downloadLength);
- fileIndex = fileStream.Length;
- var percentage =(double)fileIndex / fileSize;
- progressCallback?.Invoke(percentage);
- return true;
- }
- }
- }
- catch (Exception ex)
- {
- Logger.WriteLineWarn($"Download fail, {requestUrl}, {ex}");
- return false;
- }
- }
- /// <summary>
- /// 获取当前分块的长度
- /// </summary>
- /// <param name="streamLength"></param>
- /// <param name="chunkSize"></param>
- /// <param name="fileSize"></param>
- /// <returns></returns>
- private long GetNewLength(long streamLength, long chunkSize, long fileSize)
- {
- var newChunk = streamLength + chunkSize;
- return newChunk > fileSize ? fileSize : newChunk;
- }
- /// <summary>
- /// 删除文件
- /// </summary>
- /// <param name="fileName"></param>
- /// <returns></returns>
- public bool DeleteFile(string requestUrl, string authorization)
- {
- if (string.IsNullOrWhiteSpace(authorization))
- {
- Logger.WriteLineError("authorization can't be empty");
- return false;
- }
- if (string.IsNullOrWhiteSpace(requestUrl))
- {
- Logger.WriteLineError("requestUrl can't be empty");
- return false;
- }
- if (_objectUserAgent == null)
- {
- throw new Exception("UFileConfig not set");
- }
- using (var request = new HttpRequestMessage())
- {
- request.RequestUri = new Uri(requestUrl);
- request.Method = HttpMethod.Delete;
- request.Headers.UserAgent.Add(new ProductInfoHeaderValue(_objectUserAgent.ProductName, _objectUserAgent.Version));
- request.Headers.TryAddWithoutValidation("Authorization", authorization);
- return HttpClientHelper.ExecuteRequest(request, HttpClientHelper.GetBooleanResult);
- }
- }
- /// <summary>
- /// 查找文件
- /// </summary>
- /// <param name="prefix"></param>
- /// <returns></returns>
- public ObjectFileItemList SearchFiles(string requestUrl, string authorization)
- {
- if (string.IsNullOrWhiteSpace(authorization))
- {
- Logger.WriteLineError("authorization can't be empty");
- return null;
- }
- if (string.IsNullOrWhiteSpace(requestUrl))
- {
- Logger.WriteLineError("requestUrl can't be empty");
- return null;
- }
- using (var request = new HttpRequestMessage())
- {
- request.RequestUri = new Uri(requestUrl);
- request.Method = HttpMethod.Get;
- request.Headers.UserAgent.Add(new ProductInfoHeaderValue(_objectUserAgent.ProductName, _objectUserAgent.Version));
- request.Headers.Add("Authorization", authorization);
- return HttpClientHelper.ExecuteRequest(request, HttpClientHelper.GetJsonDataResult<ObjectFileItemList>);
- }
- }
- /// <summary>
- /// 批量删除文件
- /// </summary>
- /// <param name="uFileInfos"></param>
- /// <param name="progressCallback"></param>
- /// <returns></returns>
- public bool DeleteFiles(List<ObjectFileInfo> uFileInfos, Action<double> progressCallback = null)
- {
- if (_objectUserAgent == null)
- {
- throw new Exception("UFileConfig not set");
- }
- ConcurrentQueue<QueueRequestEntity> httpRequestMessageQueue = new ConcurrentQueue<QueueRequestEntity>();
- int queueIndex = 1;
- foreach (var file in uFileInfos)
- {
- var request = new HttpRequestMessage();
- request.RequestUri = new Uri(file.RequestUrl);
- request.Method = HttpMethod.Delete;
- request.Headers.Add("Authorization", file.Authorization);
- httpRequestMessageQueue.Enqueue(new QueueRequestEntity
- {
- FileInfo = file,
- QueueCount = uFileInfos.Count,
- QueueIndex = queueIndex,
- ProgressCallback = progressCallback,
- Request = request,
- CompleteWorker = DeleteFileCallback
- });
- queueIndex++;
- }
- var result = HttpClientHelper.ExecuteRequestQueue(httpRequestMessageQueue);
- return result;
- }
- /// <summary>
- /// 删除文件回调
- /// </summary>
- /// <param name="queueWorkItem"></param>
- private void DeleteFileCallback(QueueWorkItem queueWorkItem)
- {
- queueWorkItem.ProgressCallback?.Invoke((int)(100.0 * queueWorkItem.QueueIndex / queueWorkItem.QueueCount));
- }
- public long GetFileLength(string requestUrl)
- {
- using (var requestHead = new HttpRequestMessage())
- {
- try
- {
- requestHead.RequestUri = new Uri(requestUrl);
- requestHead.Method = HttpMethod.Head;
- return HttpClientHelper.ExecuteRequest(requestHead, HttpClientHelper.GetLengthResult);
- }
- catch (Exception ex)
- {
- Logger.WriteLineError($"Get file head error {ex}");
- }
- }
- return 0;
- }
- }
- }
|