123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346 |
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Threading;
- using System.Threading.Tasks;
- using Vinno.IUS.Common.IO;
- using Vinno.IUS.Common.Log;
- using Vinno.IUS.Common.Network.Leaf;
- using Vinno.vCloud.Common.Storage.ObjectStorageInfo;
- using Vinno.vCloud.Protocol.Infrastructures;
- namespace Vinno.vCloud.Common.Storage.Download
- {
- public class DownloadHelper
- {
- private static Dictionary<StorageType, IDownloader> _storagers;
- private static readonly object progressLock = new object();
- static DownloadHelper()
- {
- _storagers = new Dictionary<StorageType, IDownloader>();
- _storagers.Add(StorageType.Default, new VCloudStorageDownloader());
- _storagers.Add(StorageType.ObjectStorage, new ObjectStorageDownloader());
- }
- /// <summary>
- /// download file(Breakpoint continuingly)
- /// if the file size is less than 4M return byteBuffer ,else return FileBuffer
- /// </summary>
- /// <param name="creator"></param>
- /// <param name="fileToken"></param>
- /// <param name="progress"></param>
- /// <param name="cancelTokenSource"></param>
- /// <param name="timeout"></param>
- /// <returns></returns>
- public static IBuffer GetFile(string fileToken,string fileCacchePath = "", Action<double> progress = null,
- CancellationTokenSource cancelTokenSource = null, int timeout = 0)
- {
- try
- {
- // Logger.WriteLineInfo($"Get file buffer done with file token:{fileToken}");
- var tokenInfo = new FileTokenInfo(fileToken);
- var result = _storagers[tokenInfo.StorageType].GetFile(tokenInfo, fileCacchePath, progress, cancelTokenSource, timeout);
- // Logger.WriteLineInfo($"Get file buffer with file token done");
- return result;
- }
- catch (Exception ex)
- {
- Logger.WriteLineError($"GetFile Exception:{ex}");
- return null;
- }
- }
- /// <summary>
- /// Get file from storage (Vinno storage or ufile)
- /// </summary>
- /// <param name="fileToken"></param>
- /// <param name="filePath">download file to fileth</param>
- /// <param name="progress"></param>
- /// <param name="cancelTokenSource"></param>
- public static void GetFile(string fileToken, string filePath, Action<double> progress = null, CancellationTokenSource cancelTokenSource = null,bool isUseCDNNode = true)
- {
- try
- {
- //Logger.WriteLineInfo($"Get file done with file token:{fileToken}");
- var tokenInfo = new FileTokenInfo(fileToken);
- _storagers[tokenInfo.StorageType].GetFile(tokenInfo, filePath, progress, cancelTokenSource, isUseCDNNode);
- }
- catch (Exception ex)
- {
- Logger.WriteLineError($"GetFile Exception:{ex}");
- }
- }
- /// <summary>
- /// download large file by file tokens
- /// </summary>
- /// <param name="tokens"></param>
- /// <param name="filePath"></param>
- /// <param name="progress"></param>
- /// <param name="cancelTokenSource">每次必须是新的</param>
- /// <param name="isUseCDNNode"></param>
- public static void GetLargeFile(IList<string> tokens,string filePath, Action<double> progress = null, CancellationTokenSource cancelTokenSource = null, bool isUseCDNNode = true)
- {
-
- var files = new List<string>();
- progress.Invoke(0.0001);
- var count = tokens.Count;
- var totalCount = count;
- tokens.AsParallel().WithDegreeOfParallelism(5).ForAll((token) =>
- {
- if (cancelTokenSource != null && cancelTokenSource.IsCancellationRequested)
- {
- return;
- }
- var tokenInfo = new FileTokenInfo(token);
- var floder = Path.GetDirectoryName(filePath);
- var fileName = token.Substring(token.LastIndexOf('/') + 1);
- var path = Path.Combine(floder, fileName);
- var isNeedWrite = false;
- if (File.Exists(path))
- {
- using (FileStream tempStream = new FileStream(path, FileMode.OpenOrCreate))
- {
- if (tempStream.Length == 0)
- {
- isNeedWrite = true;
- }
- }
- }
- if (!File.Exists(path) || isNeedWrite)
- {
- _storagers[tokenInfo.StorageType].GetFile(tokenInfo, path, null, cancelTokenSource, isUseCDNNode);
- }
- if (cancelTokenSource != null && cancelTokenSource.IsCancellationRequested)
- {
- progress.Invoke(0.0);
- return;
- }
- files.Add(path);
- lock (progressLock)
- {
- totalCount--;
- progress.Invoke((double)(count - totalCount) / count * 0.9);
- }
-
- });
- if (cancelTokenSource != null && cancelTokenSource.IsCancellationRequested)
- {
- progress.Invoke(0.0);
- return;
- }
- var result = CombineFiles(files, filePath, progress);
- if (result)
- {
- progress.Invoke(1.0);
- ClearFiles(files);
- }
- }
- /// <summary>
- /// Get File Async
- /// </summary>
- /// <param name="creator"></param>
- /// <param name="fileToken"></param>
- /// <param name="filePath"></param>
- /// <param name="progress"></param>
- /// <param name="cancelTokenSource"></param>
- public static async Task GetFileAsync(string fileToken, string filePath,
- Action<double> progress = null, CancellationTokenSource cancelTokenSource = null)
- {
- try
- {
- // Logger.WriteLineInfo($"Async get file done with file token:{fileToken}");
- var tokenInfo = new FileTokenInfo(fileToken);
- await _storagers[tokenInfo.StorageType].GetFileAsync(tokenInfo, filePath, progress, cancelTokenSource);
- }
- catch (Exception ex)
- {
- Logger.WriteLineError($"GetFileAsync Exception:{ex}");
- }
- }
- /// <summary>
- /// Get File Async
- /// </summary>
- /// <param name="creator"></param>
- /// <param name="fileToken"></param>
- /// <param name="filePath"></param>
- /// <param name="progress"></param>
- /// <param name="cancelTokenSource"></param>
- public static async Task<IBuffer> GetFileAsync(string fileToken, string cacheFilePath,
- Action<double> progress = null, CancellationTokenSource cancelTokenSource = null,int timeout = 0)
- {
- try
- {
- Logger.WriteLineInfo($"Async get file buffer done with file token:{fileToken}");
- var tokenInfo = new FileTokenInfo(fileToken);
- var result = await _storagers[tokenInfo.StorageType].GetFileAsync(tokenInfo, cacheFilePath, progress, cancelTokenSource, timeout);
- return result;
- }
- catch (Exception ex)
- {
- Logger.WriteLineError($"GetFileAsync Exception:{ex}");
- return null;
- }
- }
- /// <summary>
- /// 批量获取文件
- /// </summary>
- /// <param name="creator">TCPCreator,UFile时不用传</param>
- /// <param name="fileTokens">文件Token列表</param>
- /// <param name="progress">进度回调</param>
- /// <param name="cancelTokenSource">取消标识,UFile时不可取消</param>
- /// <returns>文件内容列表</returns>
- public static IEnumerable<byte[]> GetFiles(IList<string> fileTokens,
- CancellationTokenSource cancelTokenSource = null, ClientLeaf storageLeaf = null)
- {
- try
- {
- var stroageType = StorageType.Default;
- var fileTokenList = new List<FileTokenInfo>();
- foreach (var token in fileTokens)
- {
- var tokenInfo = new FileTokenInfo(token);
- stroageType = tokenInfo.StorageType;
- fileTokenList.Add(tokenInfo);
- }
- return _storagers[stroageType].GetFiles(fileTokenList, cancelTokenSource, storageLeaf);
- }
- catch (Exception ex)
- {
- Logger.WriteLineError($"GetFiles Exception:{ex}");
- return null;
- }
- }
- /// <summary>
- /// download file(Breakpoint continuingly)
- /// if the file size is less than 4M return byteBuffer ,else return FileBuffer
- /// </summary>
- /// <param name="creator"></param>
- /// <param name="fileToken"></param>
- /// <param name="from"></param>
- /// <param name="to"></param>IE
- /// <param name="progress"></param>
- /// <param name="cancelTokenSource"></param>
- /// <param name="timeout"></param>
- /// <returns></returns>
- public static IBuffer GetFile(string fileToken, string cacheFilePath, long from, long to, Action<double> progress = null,
- CancellationTokenSource cancelTokenSource = null, int timeout = 0)
- {
- try
- {
- Logger.WriteLineInfo($"Get file2 buffer done with file token:{fileToken}");
- var tokenInfo = new FileTokenInfo(fileToken);
- var stroageType = tokenInfo.StorageType;
- var result = _storagers[stroageType].GetFile(tokenInfo, cacheFilePath, from, to, progress, cancelTokenSource, timeout);
- return result;
- }
- catch (Exception ex)
- {
- Logger.WriteLineError($"GetFile Exception:{ex}");
- return null;
- }
- }
- /// <summary>
- /// 获取更新文件(批量)
- /// </summary>
- /// <param name="tempFolder"></param>
- /// <param name="upgradeType"></param>
- /// <param name="currentVersion"></param>
- /// <returns></returns>
- public static bool DownloadFiles(string tempFolder, List<ObjectFileInfo> fileList, Action<double> progressCallback)
- {
- try
- {
- return _storagers[StorageType.ObjectStorage].DownloadFiles(tempFolder, fileList, progressCallback);
- }
- catch (Exception ex)
- {
- Logger.WriteLineError($"DownloadFiles Exception:{ex}");
- return false;
- }
- }
- /// <summary>
- /// 合并文件
- /// </summary>
- /// <param name="filePaths">要合并的文件列表</param>
- /// <param name="combineFile">合并后的文件路径带文件名</param>
- static bool CombineFiles(List<string> filePaths, string combineFile, Action<double> progress = null)
- {
- try
- {
- var fileDictionary = new Dictionary<int, string>();
- foreach (var f in filePaths)
- {
- if (int.TryParse(f.Substring(f.LastIndexOf("part") + 4), out int key))
- {
- fileDictionary.Add(key, f);
- }
- else
- {
- Logger.WriteLineError($"TryParse part error in {f}");
- return false;
- }
- }
- var count = filePaths.Count();
- var progressValue = 0.0;
- using (FileStream CombineStream = new FileStream(combineFile, FileMode.OpenOrCreate))
- {
- using (BinaryWriter CombineWriter = new BinaryWriter(CombineStream))
- {
- for (var i = 0; i < count; i++)
- {
- var file = fileDictionary.FirstOrDefault(x=>x.Key == i).Value;
- using (FileStream fileStream = new FileStream(file, FileMode.Open))
- {
- using (BinaryReader fileReader = new BinaryReader(fileStream))
- {
- byte[] TempBytes = fileReader.ReadBytes((int)fileStream.Length);
- CombineWriter.Write(TempBytes);
- }
- }
- progressValue += 1.0 / count * 0.1;
- progress?.Invoke(progressValue + 0.9);
- }
- return true;
- }
- }
- }
- catch (Exception ex)
- {
- Logger.WriteLineInfo($"CombineFiles exception:{ex}");
- return false;
- }
- }
- /// <summary>
- /// 批量清理文件
- /// </summary>
- /// <param name="files"></param>
- static void ClearFiles(IList<string> files)
- {
- Task.Run(() =>
- {
- try
- {
- foreach (var f in files)
- {
- File.Delete(f);
- }
- }
- catch (Exception ex)
- {
- Logger.WriteLineError($"delete file ex:{ex}");
- }
- });
- }
- }
- }
|