📄 transportingfile.cs
字号:
namespace Imps.Client.Core.P2P.FileTransportor
{
using Imps.Client.Core.P2P;
using Imps.Client.Core.P2P.ICE;
using Imps.Client.Utils;
using NCindy.Util;
using NCindy.Util.Logging;
using System;
using System.IO;
using System.Runtime.InteropServices;
public class TransportingFile : TransFileInfo, IDisposable
{
private short currentBlockID;
private const int FileBufferSize = 0x200000;
private FileStream innerFileStream;
private readonly bool isSender;
private static readonly ILogger log = LogFactory.CreateLogger(MethodBase.GetCurrentMethod().ReflectedType);
private const int MaxMD5Size = 0x6400000;
private readonly Peer remotePeer;
private readonly string tempFileName;
private byte transportingID;
private readonly ITransportManager transportManager;
public TransportingFile(string localFilePath) : this(localFilePath, (long) 0)
{
}
public TransportingFile(string localFilePath, long initCompletedSize)
{
this.isSender = true;
base.LocalFilePath = localFilePath;
if (File.Exists(localFilePath))
{
base.FileSize = new FileInfo(base.LocalFilePath).Length;
this.GetFirst100MMD5();
this.innerFileStream = new FileStream(base.LocalFilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
this.currentBlockID = (short) (initCompletedSize / ((long) 0x8000));
base.CompletedSize = initCompletedSize;
this.innerFileStream.Position = initCompletedSize;
}
}
public TransportingFile(string localFilePath, long fileSize, string sourceFileName, long completedLength, string first100Mmd5, Peer remotePeer)
{
this.isSender = false;
base.FileSize = fileSize;
base.CompletedSize = completedLength;
base.First100MMd5 = first100Mmd5;
base.SourceFileName = sourceFileName;
this.remotePeer = remotePeer;
base.SourceSID = remotePeer.Sid;
try
{
this.transportManager = P2PManager.Instace.LocalUser.TransportManager;
this.transportManager.GetFileInfo(this);
}
catch (Exception exception)
{
ClientLogger.WriteException(exception);
}
if (!string.IsNullOrEmpty(localFilePath))
{
this.transportManager.UpdateLocalFilePath(base.Id, localFilePath);
base.LocalFilePath = localFilePath;
}
if (string.IsNullOrEmpty(base.LocalFilePath))
{
this.tempFileName = string.Empty;
}
else
{
this.tempFileName = base.LocalFilePath + ".ftn";
}
if (string.IsNullOrEmpty(this.tempFileName))
{
base.CompletedSize = 0;
}
else if (File.Exists(this.tempFileName))
{
this.innerFileStream = new FileStream(this.tempFileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, 0x200000);
this.innerFileStream.Position = base.CompletedSize;
}
else
{
base.CompletedSize = 0;
this.CreateEmptyFile();
}
}
public void Close()
{
if (this.innerFileStream != null)
{
this.innerFileStream.Dispose();
}
if ((!this.isSender && !string.IsNullOrEmpty(this.tempFileName)) && File.Exists(this.tempFileName))
{
try
{
if (base.CompletedSize == 0)
{
this.transportManager.DeleteCompletedFile(base.Id);
File.Delete(this.tempFileName);
}
else if (base.CompletedSize == base.FileSize)
{
File.Move(this.tempFileName, base.LocalFilePath);
this.transportManager.DeleteCompletedFile(base.Id);
}
else
{
this.transportManager.UpdateCompletedSize(base.Id, base.CompletedSize);
}
}
catch (Exception exception)
{
if (log.IsWarnEnabled)
{
log.Warn("Close transporting file failed.", exception);
}
}
}
}
private void CreateEmptyFile()
{
if (!this.isSender)
{
if (log.IsInfoEnabled)
{
log.Info(string.Format("Create file, file name {0}, file size {1}", base.LocalFilePath, base.FileSize));
}
this.innerFileStream = new FileStream(this.tempFileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, 0x200000);
}
}
public void Dispose()
{
try
{
this.Close();
}
catch
{
}
}
private void DoWriteFile(long offset, byte[] data, int length)
{
lock (this.innerFileStream)
{
this.innerFileStream.Position = offset;
this.innerFileStream.Write(data, 0, length);
}
}
public bool GetBlock(long begin, out DataBlock block)
{
block = new DataBlock(this, begin);
return true;
}
private void GetFirst100MMD5()
{
base.First100MMd5 = CryptoHelper.GetFileMD5(base.LocalFilePath, (long) 0, (int) Math.Min(base.FileSize, (long) 0x6400000));
}
public bool GetNextChunk(out FileChunk chunk)
{
short blockID;
chunk = null;
if ((this.currentBlockID * 0x8000) >= base.FileSize)
{
return false;
}
this.currentBlockID = (short) ((blockID = this.currentBlockID) + 1);
chunk = new FileChunk(blockID, this);
return true;
}
public void WriteToFile(DataBlock block)
{
int length = block.Data.Length;
if (log.IsInfoEnabled)
{
log.Info(string.Format("Write {0} bytes to {1}, offset: {2}", length, base.LocalFilePath, block.FileOffset));
}
long offset = block.FileOffset;
byte[] data = block.Data;
this.WriteToFile(offset, data);
}
private void WriteToFile(long offset, byte[] data)
{
try
{
this.DoWriteFile(offset, data, data.Length);
}
catch (Exception exception)
{
log.Fatal("WriteToFile(long offset, byte[] data) failed.", exception);
throw;
}
}
public void WriteToFile(long offset, byte[] data, int length)
{
this.DoWriteFile(offset, data, length);
lock (this)
{
base.CompletedSize += length;
this.transportManager.UpdateCompletedSize(base.Id, base.CompletedSize);
}
}
internal FileStream InnerFileStream
{
get
{
return this.innerFileStream;
}
}
public bool IsCompleted
{
get
{
return (base.CompletedSize == base.FileSize);
}
}
public Peer RemotePeer
{
get
{
return this.remotePeer;
}
}
public byte TransportingID
{
get
{
return this.transportingID;
}
set
{
this.transportingID = value;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -