mirror of
https://github.com/RRQM/TouchSocket.git
synced 2025-12-21 02:46:43 +08:00
修复文件
This commit is contained in:
@@ -1,40 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在RRQMCore.XREF命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace RRQMSocket.FileTransfer
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件块
|
||||
/// </summary>
|
||||
public class FileBlock
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件快索引
|
||||
/// </summary>
|
||||
public int Index { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文件流位置
|
||||
/// </summary>
|
||||
public long Position { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文件块长度
|
||||
/// </summary>
|
||||
public long UnitLength { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// 请求状态
|
||||
/// </summary>
|
||||
public RequestStatus RequestStatus { get; internal set; }
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在RRQMCore.XREF命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
using RRQMCore.IO;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace RRQMSocket.FileTransfer
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件Hash校验
|
||||
/// </summary>
|
||||
public static class FileHashGenerator
|
||||
{
|
||||
private static FileHashType fileCheckType;
|
||||
|
||||
/// <summary>
|
||||
/// 文件
|
||||
/// </summary>
|
||||
public static FileHashType FileCheckType
|
||||
{
|
||||
get { return fileCheckType; }
|
||||
set { fileCheckType = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件Hash
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetFileHash(string path)
|
||||
{
|
||||
using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
return GetFileHash(fileStream);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件Hash
|
||||
/// </summary>
|
||||
/// <param name="fileStream"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetFileHash(FileStream fileStream)
|
||||
{
|
||||
HashAlgorithm hash;
|
||||
switch (fileCheckType)
|
||||
{
|
||||
case FileHashType.MD5:
|
||||
hash = MD5.Create();
|
||||
break;
|
||||
|
||||
case FileHashType.SHA1:
|
||||
hash = SHA1.Create();
|
||||
break;
|
||||
|
||||
case FileHashType.SHA256:
|
||||
hash = SHA256.Create();
|
||||
break;
|
||||
|
||||
case FileHashType.SHA512:
|
||||
hash = SHA512.Create();
|
||||
break;
|
||||
|
||||
default:
|
||||
hash = null;
|
||||
break;
|
||||
}
|
||||
return FileControler.GetStreamHash(fileStream, hash);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,250 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在RRQMCore.XREF命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
using RRQMCore.ByteManager;
|
||||
using RRQMCore.Exceptions;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading;
|
||||
|
||||
namespace RRQMSocket.FileTransfer
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件流池
|
||||
/// </summary>
|
||||
public static class FileStreamPool
|
||||
{
|
||||
internal static ConcurrentDictionary<string, RRQMStream> pathStream = new ConcurrentDictionary<string, RRQMStream>();
|
||||
private readonly static object locker = new object();
|
||||
private static ReaderWriterLockSlim lockSlim = new ReaderWriterLockSlim();
|
||||
|
||||
internal static bool CheckAllFileBlockFinished(string path)
|
||||
{
|
||||
lock (locker)
|
||||
{
|
||||
RRQMStream stream;
|
||||
if (!pathStream.TryGetValue(path, out stream))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (stream.StreamType == StreamOperationType.Read)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
foreach (var block in stream.Blocks)
|
||||
{
|
||||
if (block.RequestStatus != RequestStatus.Finished)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void DisposeReadStream(string path)
|
||||
{
|
||||
RRQMStream stream;
|
||||
if (pathStream.TryGetValue(path, out stream))
|
||||
{
|
||||
if (Interlocked.Decrement(ref stream.reference) == 0)
|
||||
{
|
||||
if (pathStream.TryRemove(path, out stream))
|
||||
{
|
||||
stream.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void DisposeWriteStream(string path, bool finished)
|
||||
{
|
||||
RRQMStream stream;
|
||||
if (pathStream.TryGetValue(path, out stream))
|
||||
{
|
||||
if (Interlocked.Decrement(ref stream.reference) == 0)
|
||||
{
|
||||
if (pathStream.TryRemove(path, out stream))
|
||||
{
|
||||
if (finished)
|
||||
{
|
||||
stream.FinishStream();
|
||||
}
|
||||
else
|
||||
{
|
||||
stream.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool GetFreeFileBlock(string path, out FileBlock fileBlock, out string mes)
|
||||
{
|
||||
lock (locker)
|
||||
{
|
||||
RRQMStream stream;
|
||||
if (!pathStream.TryGetValue(path, out stream))
|
||||
{
|
||||
mes = "没有此路径的写入信息";
|
||||
fileBlock = null;
|
||||
return false;
|
||||
}
|
||||
if (stream.StreamType == StreamOperationType.Read)
|
||||
{
|
||||
mes = "该路径的流为只读";
|
||||
fileBlock = null;
|
||||
return false;
|
||||
}
|
||||
foreach (var block in stream.Blocks)
|
||||
{
|
||||
if (block.RequestStatus == RequestStatus.Hovering)
|
||||
{
|
||||
block.RequestStatus = RequestStatus.InProgress;
|
||||
fileBlock = block;
|
||||
mes = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
fileBlock = null;
|
||||
mes = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool LoadReadStream(ref UrlFileInfo urlFileInfo, out string mes)
|
||||
{
|
||||
RRQMStream stream;
|
||||
if (pathStream.TryGetValue(urlFileInfo.FilePath, out stream))
|
||||
{
|
||||
Interlocked.Increment(ref stream.reference);
|
||||
mes = null;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (RRQMStream.CreateReadStream(out stream, ref urlFileInfo, out mes))
|
||||
{
|
||||
Interlocked.Increment(ref stream.reference);
|
||||
pathStream.TryAdd(urlFileInfo.FilePath, stream);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool LoadWriteStream(ref ProgressBlockCollection blocks, bool onlySearch, out string mes)
|
||||
{
|
||||
RRQMStream stream;
|
||||
string rrqmPath = blocks.UrlFileInfo.SaveFullPath + ".rrqm";
|
||||
if (!pathStream.TryGetValue(rrqmPath, out stream))
|
||||
{
|
||||
if (RRQMStream.CreateWriteStream(out stream, ref blocks, out mes))
|
||||
{
|
||||
Interlocked.Increment(ref stream.reference);
|
||||
mes = null;
|
||||
return pathStream.TryAdd(rrqmPath, stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (onlySearch)
|
||||
{
|
||||
blocks = stream.Blocks;
|
||||
mes = null;
|
||||
return true;
|
||||
}
|
||||
mes = "该文件流正在被其他客户端拥有";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool ReadFile(string path, out string mes, long beginPosition, ByteBlock byteBlock, int offset, int length)
|
||||
{
|
||||
lockSlim.EnterReadLock();
|
||||
try
|
||||
{
|
||||
if (pathStream.TryGetValue(path, out RRQMStream stream))
|
||||
{
|
||||
stream.FileStream.Position = beginPosition;
|
||||
|
||||
if (byteBlock.Buffer.Length < length + offset)
|
||||
{
|
||||
byteBlock.SetBuffer(new byte[length + offset]);
|
||||
}
|
||||
|
||||
int r = stream.FileStream.Read(byteBlock.Buffer, offset, length);
|
||||
if (r == length)
|
||||
{
|
||||
byteBlock.Position = offset + length;
|
||||
byteBlock.SetLength(offset + length);
|
||||
mes = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
mes = "没有找到该路径下的流文件";
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
mes = ex.Message;
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
lockSlim.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
internal static void SaveProgressBlockCollection(string path)
|
||||
{
|
||||
RRQMStream stream;
|
||||
if (pathStream.TryGetValue(path, out stream))
|
||||
{
|
||||
stream.SaveProgressBlockCollection();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RRQMException("没有找到该路径下的流文件");
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool WriteFile(string path, out string mes, out RRQMStream stream, long streamPosition, byte[] buffer, int offset, int length)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (pathStream.TryGetValue(path, out stream))
|
||||
{
|
||||
stream.FileStream.Position = streamPosition;
|
||||
stream.FileStream.Write(buffer, offset, length);
|
||||
stream.FileStream.Flush();
|
||||
mes = null;
|
||||
return true;
|
||||
}
|
||||
mes = "未找到该路径下的流";
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
mes = ex.Message;
|
||||
stream = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在RRQMCore.XREF命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
using RRQMCore.Exceptions;
|
||||
|
||||
namespace RRQMSocket.FileTransfer
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件传输错误码映射
|
||||
/// </summary>
|
||||
public class FileTransferErrorExceptionMapping : ErrorExceptionMapping
|
||||
{
|
||||
private static FileTransferErrorExceptionMapping _instance = new FileTransferErrorExceptionMapping();
|
||||
|
||||
/// <summary>
|
||||
/// 默认实例
|
||||
/// </summary>
|
||||
public static FileTransferErrorExceptionMapping Default { get => _instance; }
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在RRQMCore.XREF命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
using RRQMCore.Run;
|
||||
|
||||
namespace RRQMSocket.FileTransfer
|
||||
{
|
||||
internal class FileWaitResult : WaitResult
|
||||
{
|
||||
public PBCollectionTemp PBCollectionTemp { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在RRQMCore.XREF命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace RRQMSocket.FileTransfer
|
||||
{
|
||||
/// <summary>
|
||||
/// 临时序列化
|
||||
/// </summary>
|
||||
public class PBCollectionTemp
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件信息
|
||||
/// </summary>
|
||||
public UrlFileInfo UrlFileInfo { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// 块集合
|
||||
/// </summary>
|
||||
public List<FileBlock> Blocks { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// 从文件块转换
|
||||
/// </summary>
|
||||
/// <param name="progressBlocks"></param>
|
||||
/// <returns></returns>
|
||||
public static PBCollectionTemp GetFromProgressBlockCollection(ProgressBlockCollection progressBlocks)
|
||||
{
|
||||
if (progressBlocks == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
PBCollectionTemp collectionTemp = new PBCollectionTemp();
|
||||
collectionTemp.UrlFileInfo = progressBlocks.UrlFileInfo;
|
||||
collectionTemp.Blocks = new List<FileBlock>();
|
||||
collectionTemp.Blocks.AddRange(progressBlocks);
|
||||
return collectionTemp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为ProgressBlockCollection
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ProgressBlockCollection ToPBCollection()
|
||||
{
|
||||
ProgressBlockCollection progressBlocks = new ProgressBlockCollection();
|
||||
progressBlocks.UrlFileInfo = this.UrlFileInfo;
|
||||
if (this.Blocks != null)
|
||||
{
|
||||
progressBlocks.AddRange(this.Blocks);
|
||||
}
|
||||
return progressBlocks;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在RRQMCore.XREF命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
using RRQMCore.Serialization;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace RRQMSocket.FileTransfer
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件进度块集合
|
||||
/// </summary>
|
||||
public class ProgressBlockCollection : ReadOnlyList<FileBlock>
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件信息
|
||||
/// </summary>
|
||||
public UrlFileInfo UrlFileInfo { get; internal set; }
|
||||
|
||||
private static int blockLength = 1024 * 1024 * 10;
|
||||
|
||||
/// <summary>
|
||||
/// 分块长度,min=1024*1024*5
|
||||
/// </summary>
|
||||
public static int BlockLength
|
||||
{
|
||||
get { return blockLength; }
|
||||
set
|
||||
{
|
||||
if (value < 1024 * 1024 * 5)
|
||||
{
|
||||
value = 1024 * 1024 * 5;
|
||||
}
|
||||
blockLength = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
internal void Save(string path)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
File.Delete(path);
|
||||
}
|
||||
byte[] buffer = SerializeConvert.RRQMBinarySerialize(this, true);
|
||||
using (FileStream fileStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite))
|
||||
{
|
||||
fileStream.Write(buffer, 0, buffer.Length);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
internal static ProgressBlockCollection Read(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (FileStream stream = File.OpenRead(path))
|
||||
{
|
||||
byte[] buffer = new byte[stream.Length];
|
||||
stream.Read(buffer, 0, buffer.Length);
|
||||
return SerializeConvert.RRQMBinaryDeserialize<ProgressBlockCollection>(buffer, 0);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal static ProgressBlockCollection CreateProgressBlockCollection(UrlFileInfo urlFileInfo)
|
||||
{
|
||||
ProgressBlockCollection blocks = new ProgressBlockCollection();
|
||||
blocks.UrlFileInfo = urlFileInfo;
|
||||
long position = 0;
|
||||
long surLength = urlFileInfo.FileLength;
|
||||
int index = 0;
|
||||
while (surLength > 0)
|
||||
{
|
||||
FileBlock block = new FileBlock();
|
||||
block.Index = index++;
|
||||
block.RequestStatus = RequestStatus.Hovering;
|
||||
block.Position = position;
|
||||
block.UnitLength = surLength > blockLength ? blockLength : surLength;
|
||||
blocks.Add(block);
|
||||
position += block.UnitLength;
|
||||
surLength -= block.UnitLength;
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在RRQMCore.XREF命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
using RRQMCore.Serialization;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace RRQMSocket.FileTransfer
|
||||
{
|
||||
internal class RRQMStream
|
||||
{
|
||||
internal int reference;
|
||||
|
||||
private ProgressBlockCollection blocks;
|
||||
|
||||
private FileStream fileStream;
|
||||
private string rrqmPath;
|
||||
private StreamOperationType streamType;
|
||||
|
||||
private UrlFileInfo urlFileInfo;
|
||||
|
||||
private RRQMStream()
|
||||
{
|
||||
}
|
||||
|
||||
public ProgressBlockCollection Blocks { get { return blocks; } }
|
||||
|
||||
public FileStream FileStream
|
||||
{
|
||||
get { return fileStream; }
|
||||
}
|
||||
|
||||
public StreamOperationType StreamType
|
||||
{
|
||||
get { return streamType; }
|
||||
}
|
||||
|
||||
public UrlFileInfo UrlFileInfo { get => urlFileInfo; }
|
||||
|
||||
internal static bool CreateReadStream(out RRQMStream stream, ref UrlFileInfo urlFileInfo, out string mes)
|
||||
{
|
||||
stream = new RRQMStream();
|
||||
try
|
||||
{
|
||||
stream.streamType = StreamOperationType.Read;
|
||||
stream.fileStream = File.OpenRead(urlFileInfo.FilePath);
|
||||
urlFileInfo.FileLength = stream.fileStream.Length;
|
||||
stream.urlFileInfo = urlFileInfo;
|
||||
mes = null;
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
stream.Dispose();
|
||||
stream = null;
|
||||
mes = ex.Message;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool CreateWriteStream(out RRQMStream stream, ref ProgressBlockCollection blocks, out string mes)
|
||||
{
|
||||
stream = new RRQMStream();
|
||||
stream.rrqmPath = blocks.UrlFileInfo.SaveFullPath + ".rrqm";
|
||||
stream.urlFileInfo = blocks.UrlFileInfo;
|
||||
stream.streamType = StreamOperationType.Write;
|
||||
try
|
||||
{
|
||||
if (blocks.UrlFileInfo.Flags.HasFlag(TransferFlags.BreakpointResume) && File.Exists(stream.rrqmPath))
|
||||
{
|
||||
stream.fileStream = new FileStream(stream.rrqmPath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
|
||||
int blocksLength = (int)(stream.fileStream.Length - blocks.UrlFileInfo.FileLength);
|
||||
if (blocksLength > 0)
|
||||
{
|
||||
stream.fileStream.Position = blocks.UrlFileInfo.FileLength;
|
||||
byte[] buffer = new byte[blocksLength];
|
||||
stream.fileStream.Read(buffer, 0, buffer.Length);
|
||||
try
|
||||
{
|
||||
PBCollectionTemp readBlocks = SerializeConvert.RRQMBinaryDeserialize<PBCollectionTemp>(buffer);
|
||||
if (readBlocks.UrlFileInfo != null && blocks.UrlFileInfo != null && readBlocks.UrlFileInfo.FileHash != null)
|
||||
{
|
||||
if (readBlocks.UrlFileInfo.FileHash == blocks.UrlFileInfo.FileHash)
|
||||
{
|
||||
stream.blocks = blocks = readBlocks.ToPBCollection();
|
||||
mes = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
stream.fileStream.Dispose();
|
||||
}
|
||||
stream.blocks = blocks;
|
||||
if (File.Exists(stream.rrqmPath))
|
||||
{
|
||||
File.Delete(stream.rrqmPath);
|
||||
}
|
||||
stream.fileStream = new FileStream(stream.rrqmPath, FileMode.Create, FileAccess.ReadWrite);
|
||||
stream.SaveProgressBlockCollection();
|
||||
mes = null;
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
mes = ex.Message;
|
||||
stream.Dispose();
|
||||
stream = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool FinishStream()
|
||||
{
|
||||
this.fileStream.SetLength(this.urlFileInfo.FileLength);
|
||||
this.fileStream.Flush();
|
||||
UrlFileInfo info = this.urlFileInfo;
|
||||
this.Dispose();
|
||||
if (File.Exists(info.SaveFullPath))
|
||||
{
|
||||
File.Delete(info.SaveFullPath);
|
||||
}
|
||||
File.Move(info.SaveFullPath + ".rrqm", info.SaveFullPath);
|
||||
return true;
|
||||
}
|
||||
|
||||
internal void Dispose()
|
||||
{
|
||||
this.blocks = null;
|
||||
this.urlFileInfo = null;
|
||||
if (this.fileStream != null)
|
||||
{
|
||||
this.fileStream.Dispose();
|
||||
this.fileStream = null;
|
||||
}
|
||||
}
|
||||
|
||||
internal void SaveProgressBlockCollection()
|
||||
{
|
||||
byte[] dataBuffer = SerializeConvert.RRQMBinarySerialize(PBCollectionTemp.GetFromProgressBlockCollection(blocks), true);
|
||||
this.fileStream.Position = this.urlFileInfo.FileLength;
|
||||
this.fileStream.WriteAsync(dataBuffer, 0, dataBuffer.Length);
|
||||
this.fileStream.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在RRQMCore.XREF命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace RRQMSocket.FileTransfer
|
||||
{
|
||||
/// <summary>
|
||||
/// 只读
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
|
||||
public class ReadOnlyList<T> : IEnumerable<T>
|
||||
{
|
||||
private List<T> list = new List<T>();
|
||||
|
||||
internal void Add(T block)
|
||||
{
|
||||
list.Add(block);
|
||||
}
|
||||
|
||||
internal void AddRange(IEnumerable<T> collection)
|
||||
{
|
||||
list.AddRange(collection);
|
||||
}
|
||||
|
||||
internal void Remove(T block)
|
||||
{
|
||||
list.Remove(block);
|
||||
}
|
||||
|
||||
internal void RemoveAt(int index)
|
||||
{
|
||||
list.RemoveAt(index);
|
||||
}
|
||||
|
||||
internal void RemoveAll(Predicate<T> match)
|
||||
{
|
||||
list.RemoveAll(match);
|
||||
}
|
||||
|
||||
internal void RemoveRange(int index, int range)
|
||||
{
|
||||
list.RemoveRange(index, range);
|
||||
}
|
||||
|
||||
internal void Clear()
|
||||
{
|
||||
list.Clear();
|
||||
}
|
||||
|
||||
internal void Insert(int index, T item)
|
||||
{
|
||||
list.Insert(index, item);
|
||||
}
|
||||
|
||||
internal void InsertRange(int index, IEnumerable<T> collection)
|
||||
{
|
||||
list.InsertRange(index, collection);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回迭代器
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
return this.list.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return this.list.GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
public T this[int index] { get { return list[index]; } }
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在RRQMCore.XREF命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
namespace RRQMSocket.FileTransfer
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
internal class Speed
|
||||
{
|
||||
internal static long downloadSpeed;
|
||||
internal static long uploadSpeed;
|
||||
}
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在RRQMCore.XREF命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RRQMSocket.FileTransfer
|
||||
{
|
||||
/// <summary>
|
||||
/// 传输集合
|
||||
/// </summary>
|
||||
public class TransferCollection : IEnumerable<UrlFileInfo>
|
||||
{
|
||||
internal TransferCollection()
|
||||
{
|
||||
list = new List<UrlFileInfo>();
|
||||
}
|
||||
|
||||
internal event RRQMMessageEventHandler OnCollectionChanged;
|
||||
|
||||
private List<UrlFileInfo> list;
|
||||
|
||||
/// <summary>
|
||||
/// 返回一个循环访问集合的枚举器
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerator<UrlFileInfo> GetEnumerator()
|
||||
{
|
||||
return list.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return list.GetEnumerator();
|
||||
}
|
||||
|
||||
internal void Add(UrlFileInfo fileInfo)
|
||||
{
|
||||
this.list.Add(fileInfo);
|
||||
Task.Run(() =>
|
||||
{
|
||||
OnCollectionChanged?.Invoke(null, new MesEventArgs("添加"));
|
||||
});
|
||||
}
|
||||
|
||||
internal void Clear()
|
||||
{
|
||||
this.list.Clear();
|
||||
Task.Run(() =>
|
||||
{
|
||||
OnCollectionChanged?.Invoke(null, new MesEventArgs("清空"));
|
||||
});
|
||||
}
|
||||
|
||||
internal bool Remove(UrlFileInfo fileInfo)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
OnCollectionChanged?.Invoke(null, new MesEventArgs("移除"));
|
||||
});
|
||||
return this.list.Remove(fileInfo);
|
||||
}
|
||||
|
||||
internal bool GetFirst(out UrlFileInfo fileInfo)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (this.list.Count > 0)
|
||||
{
|
||||
fileInfo = this.list[0];
|
||||
this.list.RemoveAt(0);
|
||||
Task.Run(() =>
|
||||
{
|
||||
OnCollectionChanged?.Invoke(null, new MesEventArgs("进入传输"));
|
||||
});
|
||||
return true;
|
||||
}
|
||||
fileInfo = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,203 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在RRQMCore.XREF命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
|
||||
namespace RRQMSocket.FileTransfer
|
||||
{
|
||||
/// <summary>
|
||||
/// 传输文件Hash暂存字典
|
||||
/// </summary>
|
||||
public static class TransferFileHashDictionary
|
||||
{
|
||||
private static ConcurrentDictionary<string, UrlFileInfo> fileHashAndInfo = new ConcurrentDictionary<string, UrlFileInfo>();
|
||||
private static ConcurrentDictionary<string, UrlFileInfo> filePathAndInfo = new ConcurrentDictionary<string, UrlFileInfo>();
|
||||
|
||||
/// <summary>
|
||||
/// 字典存储文件Hash的最大数量,默认为10000
|
||||
/// </summary>
|
||||
public static int MaxCount { get; set; } = 10000;
|
||||
|
||||
/// <summary>
|
||||
/// 添加文件信息
|
||||
/// </summary>
|
||||
/// <param name="filePath"></param>
|
||||
/// <param name="breakpointResume"></param>
|
||||
/// <returns></returns>
|
||||
public static UrlFileInfo AddFile(string filePath, bool breakpointResume = true)
|
||||
{
|
||||
UrlFileInfo urlFileInfo = new UrlFileInfo();
|
||||
using (FileStream stream = File.OpenRead(filePath))
|
||||
{
|
||||
urlFileInfo.FilePath = filePath;
|
||||
urlFileInfo.FileLength = stream.Length;
|
||||
urlFileInfo.FileName = Path.GetFileName(filePath);
|
||||
if (breakpointResume)
|
||||
{
|
||||
urlFileInfo.FileHash = FileHashGenerator.GetFileHash(stream);
|
||||
}
|
||||
}
|
||||
AddFile(urlFileInfo);
|
||||
return urlFileInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加文件信息
|
||||
/// </summary>
|
||||
/// <param name="urlFileInfo"></param>
|
||||
public static void AddFile(UrlFileInfo urlFileInfo)
|
||||
{
|
||||
if (urlFileInfo == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
filePathAndInfo.AddOrUpdate(urlFileInfo.FilePath, urlFileInfo, (key, oldValue) =>
|
||||
{
|
||||
return urlFileInfo;
|
||||
});
|
||||
|
||||
if (!string.IsNullOrEmpty(urlFileInfo.FileHash))
|
||||
{
|
||||
fileHashAndInfo.AddOrUpdate(urlFileInfo.FileHash, urlFileInfo, (key, oldValue) =>
|
||||
{
|
||||
return urlFileInfo;
|
||||
});
|
||||
}
|
||||
|
||||
if (filePathAndInfo.Count > MaxCount)
|
||||
{
|
||||
foreach (var item in filePathAndInfo.Keys)
|
||||
{
|
||||
if (filePathAndInfo.TryRemove(item, out _))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fileHashAndInfo.Count > MaxCount)
|
||||
{
|
||||
foreach (var item in fileHashAndInfo.Keys)
|
||||
{
|
||||
if (fileHashAndInfo.TryRemove(item, out _))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除全部
|
||||
/// </summary>
|
||||
public static void ClearDictionary()
|
||||
{
|
||||
if (filePathAndInfo == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
filePathAndInfo.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件信息
|
||||
/// </summary>
|
||||
/// <param name="filePath"></param>
|
||||
/// <param name="urlFileInfo"></param>
|
||||
/// <param name="breakpointResume"></param>
|
||||
/// <returns></returns>
|
||||
public static bool GetFileInfo(string filePath, out UrlFileInfo urlFileInfo, bool breakpointResume)
|
||||
{
|
||||
if (filePathAndInfo == null)
|
||||
{
|
||||
urlFileInfo = null;
|
||||
return false;
|
||||
}
|
||||
if (filePathAndInfo.ContainsKey(filePath))
|
||||
{
|
||||
urlFileInfo = filePathAndInfo[filePath];
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
using (FileStream stream = File.OpenRead(filePath))
|
||||
{
|
||||
if (urlFileInfo.FileLength == stream.Length)
|
||||
{
|
||||
if (breakpointResume && urlFileInfo.FileHash == null)
|
||||
{
|
||||
urlFileInfo.FileHash = FileHashGenerator.GetFileHash(stream);
|
||||
AddFile(urlFileInfo);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
urlFileInfo = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过FileHash获取文件信息
|
||||
/// </summary>
|
||||
/// <param name="fileHash"></param>
|
||||
/// <param name="urlFileInfo"></param>
|
||||
/// <returns></returns>
|
||||
public static bool GetFileInfoFromHash(string fileHash, out UrlFileInfo urlFileInfo)
|
||||
{
|
||||
if (fileHashAndInfo == null)
|
||||
{
|
||||
urlFileInfo = null;
|
||||
return false;
|
||||
}
|
||||
if (string.IsNullOrEmpty(fileHash))
|
||||
{
|
||||
urlFileInfo = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fileHashAndInfo.TryGetValue(fileHash, out urlFileInfo))
|
||||
{
|
||||
if (urlFileInfo.FileHash == fileHash)
|
||||
{
|
||||
if (File.Exists(urlFileInfo.FilePath))
|
||||
{
|
||||
using (FileStream stream = File.OpenRead(urlFileInfo.FilePath))
|
||||
{
|
||||
if (urlFileInfo.FileLength == stream.Length)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
urlFileInfo = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除
|
||||
/// </summary>
|
||||
/// <param name="filePath"></param>
|
||||
/// <returns></returns>
|
||||
public static bool Remove(string filePath)
|
||||
{
|
||||
if (filePathAndInfo == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return filePathAndInfo.TryRemove(filePath, out _);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在RRQMCore.XREF命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace RRQMSocket.FileTransfer
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件信息类
|
||||
/// </summary>
|
||||
public class UrlFileInfo
|
||||
{
|
||||
private string saveFullPath = string.Empty;
|
||||
|
||||
private int timeout = 30 * 1000;
|
||||
|
||||
/// <summary>
|
||||
/// 文件哈希值
|
||||
/// </summary>
|
||||
public string FileHash { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文件大小
|
||||
/// </summary>
|
||||
public long FileLength { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文件名
|
||||
/// </summary>
|
||||
public string FileName { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文件路径
|
||||
/// </summary>
|
||||
public string FilePath { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// 传输标识
|
||||
/// </summary>
|
||||
public TransferFlags Flags { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 携带消息
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 存放目录
|
||||
/// </summary>
|
||||
public string SaveFullPath
|
||||
{
|
||||
get { return saveFullPath; }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
value = string.Empty;
|
||||
}
|
||||
saveFullPath = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 超时时间,默认30*1000 ms
|
||||
/// </summary>
|
||||
public int Timeout
|
||||
{
|
||||
get { return timeout; }
|
||||
set { timeout = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 请求传输类型
|
||||
/// </summary>
|
||||
public TransferType TransferType { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// 生成下载请求必要信息
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="flags"></param>
|
||||
/// <returns></returns>
|
||||
public static UrlFileInfo CreateDownload(string path, TransferFlags flags)
|
||||
{
|
||||
UrlFileInfo fileInfo = new UrlFileInfo();
|
||||
fileInfo.FilePath = path;
|
||||
fileInfo.Flags = flags;
|
||||
fileInfo.FileName = Path.GetFileName(path);
|
||||
fileInfo.TransferType = TransferType.Download;
|
||||
return fileInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成上传请求必要信息
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="flags"></param>
|
||||
/// <returns></returns>
|
||||
public static UrlFileInfo CreateUpload(string path, TransferFlags flags)
|
||||
{
|
||||
UrlFileInfo fileInfo = new UrlFileInfo();
|
||||
fileInfo.TransferType = TransferType.Upload;
|
||||
using (FileStream stream = File.OpenRead(path))
|
||||
{
|
||||
fileInfo.Flags = flags;
|
||||
fileInfo.FilePath = path;
|
||||
if (flags.HasFlag(TransferFlags.BreakpointResume) || flags.HasFlag(TransferFlags.QuickTransfer))
|
||||
{
|
||||
fileInfo.FileHash = FileHashGenerator.GetFileHash(stream);
|
||||
}
|
||||
fileInfo.FileLength = stream.Length;
|
||||
fileInfo.FileName = Path.GetFileName(path);
|
||||
}
|
||||
|
||||
return fileInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 复制
|
||||
/// </summary>
|
||||
/// <param name="urlFileInfo"></param>
|
||||
public void CopyFrom(UrlFileInfo urlFileInfo)
|
||||
{
|
||||
this.FileHash = urlFileInfo.FileHash;
|
||||
this.FileLength = urlFileInfo.FileLength;
|
||||
this.FileName = urlFileInfo.FileName;
|
||||
this.FilePath = urlFileInfo.FilePath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断参数是否相同
|
||||
/// </summary>
|
||||
/// <param name="urlFileInfo"></param>
|
||||
/// <returns></returns>
|
||||
public bool Equals(UrlFileInfo urlFileInfo)
|
||||
{
|
||||
if (urlFileInfo.FileHash != this.FileHash)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (urlFileInfo.FileLength != this.FileLength)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (urlFileInfo.FileName != this.FileName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (urlFileInfo.FilePath != this.FilePath)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user