Ejemplo n.º 1
0
        public void CreateAndDeleteFile(IFileInfo fi)
        {
            IFileStream fs = fi.Create();

            fs.Close();
            fi.Delete();
        }
        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="fileStream">读取文件流</param>
        /// <param name="remoteFileName">远程文件名</param>
        /// <param name="onSelectedFileTransferMode">选择覆盖模式</param>
        /// <returns></returns>
        public async Task UploadFile(
            IFileStream fileStream,
            string remoteFileName,
            Func <string, TransferMode> onSelectedFileTransferMode)
        {
reset:

            LogHelper.DebugWriteLog("begin upload");
            var responsed = await this.AwaitOpenUploadFileStatus(remoteFileName); //获取远程文件状态

            if (responsed.IsNull())                                               //返回null表示等待结果期间连接中断
            {
                var isReset = await this.AwaitResetUploadFile();

                if (isReset)
                {
                    goto reset;
                }
                else
                {
                    fileStream.Close();
                    return;
                }
            }

            long position = 0;
            int  fileMode = 0;//0覆盖,1续传,2跳过

            if (responsed.Status == 1)
            {
                TransferMode transferMode = TransferMode.Continuingly;
                if (!_transferMode.HasValue)
                {
                    transferMode = onSelectedFileTransferMode.Invoke(remoteFileName);
                }
                else
                {
                    transferMode = _transferMode.Value;
                }

                switch (transferMode)
                {
                case TransferMode.Replace:
                    fileMode = 0;
                    break;

                case TransferMode.ReplaceAll:
                    fileMode      = 0;
                    _transferMode = TransferMode.Replace;
                    break;

                case TransferMode.Continuingly:
                    fileMode = 1;
                    position = responsed.Position;
                    break;

                case TransferMode.ContinuinglyAll:
                    fileMode      = 1;
                    position      = responsed.Position;
                    _transferMode = TransferMode.Continuingly;
                    break;

                case TransferMode.JumpOver:
                    CancelTransfer();
                    return;

                case TransferMode.Cancel:
                    CancelTransfer();
                    _transferMode = transferMode;
                    return;

                default:
                    break;
                }
            }
            else if (responsed.Status == 2)//文件访问失败
            {
                fileStream.Close();
                return;
            }

            fileStream.Position = position;
            var fileSize = fileStream.Length;

            this.OnFileTransferProgressEventHandler?.Invoke(this, FileTransferFlag.Begin, remoteFileName, position, fileSize);

            var data = await Task.Run(() => this.ReadFileStream(fileStream));

            SendTo(CurrentSession, MessageHead.S_FILE_FRIST_DATA,//上传首数据块,带文件选项及长度
                   new FileFristUploadDataPack()
            {
                FileMode = fileMode,
                Position = position,
                FileSize = fileStream.Length,
                Data     = data
            });

            while (true)
            {
                if (TransferTaskFlage == TransferTaskFlage.Abort)
                {
                    //停止
                    this.RemoteTaskStop();
                    fileStream.Close();
                    break;
                }

                if (fileStream.Position == fileStream.Length || fileMode == 2)
                {
                    //传输完成,或者跳过
                    fileStream.Close();
                    break;
                }
                position += data.Length;
                if (!await this.AwaitGetNextFileData())
                {
                    var isReset = await this.AwaitResetUploadFile();

                    if (isReset)
                    {
                        goto reset;
                    }
                    else
                    {
                        fileStream.Close();
                        break;
                    }
                }

                data = await Task.Run(() => this.ReadFileStream(fileStream));

                //底层通信库在正式发送数据包前会进行组包丶压缩等操作,由于文件数据块大,所处理耗时较长,此处使用线程以防止ui发生卡顿
                await Task.Run(() => SendTo(CurrentSession, MessageHead.S_FILE_DATA,
                                            new FileUploadDataPack()
                {
                    FileSize = fileStream.Length,
                    Data = data
                }));

                this.OnFileTransferProgressEventHandler?.Invoke(this, FileTransferFlag.Transfering, remoteFileName, position, fileSize);
            }
            this.OnFileTransferProgressEventHandler?.Invoke(this, FileTransferFlag.End, remoteFileName, position, fileSize);

            //取消传输
            void CancelTransfer()
            {
                fileMode = 2;
                fileStream.Close();
                this.RemoteTaskStop();
                this.OnFileTransferProgressEventHandler?.Invoke(this, FileTransferFlag.End, remoteFileName, 0, 0);
            }
        }
        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="fileStream">文件流</param>
        /// <param name="remoteFileName">远程文件名</param>
        /// <returns></returns>
        public async Task DownloadFile(IFileStream fileStream, string remoteFileName)
        {
            //LogHelper.DebugWriteLog("begin download frist Data fileName:" + Path.GetFileName(localFileName));

            long position = fileStream.Length;

reset:
            var responsed = await this.AwaitOpenDownloadData(remoteFileName, position);//首数据包,带文件状态信息及文件分块

            var status = 0;

            //返回null表示已断开连接
            if (responsed.IsNull())
            {
                var positionNull = await this.AwaitResetDownloadFile(fileStream);//等待重新连接

                if (positionNull.HasValue)
                {
                    position = positionNull.Value;
                    goto reset;
                }
                status = 0;
            }
            else if (responsed.Status == 1) //成功打开文件
            {
                await Task.Run(() => fileStream.Write(responsed.Data, 0, responsed.Data.Length));

                status = 1;
            }
            else
            {
                status = responsed.Status;//文件访问失败
            }
            this.OnFileTransferProgressEventHandler?.Invoke(this, FileTransferFlag.Begin, remoteFileName, position, responsed.FileSize);
            while (status == 1)
            {
                if (TransferTaskFlage == TransferTaskFlage.Abort)
                {
                    //停止传输
                    this.RemoteTaskStop();
                    break;
                }
                if (fileStream.Length >= responsed.FileSize)
                {
                    break;//文件传输完成
                }
                var data = await this.AwaitDownloadDataPack().ConfigureAwait(true);

                //LogHelper.DebugWriteLog("download data:" + (data == null ? "null" : data.Data.Length.ToString()));
                if (this.WhetherClose)
                {
                    break;//传输中途关闭应用
                }
                if (data.IsNull())
                {
                    var positionNull = await this.AwaitResetDownloadFile(fileStream).ConfigureAwait(true);

                    if (!positionNull.HasValue)
                    {
                        break;//session断开期间应用被关闭
                    }
                    position = positionNull.Value;
                    goto reset;
                }
                await Task.Run(() => fileStream.Write(data.Data, 0, data.Data.Length));

                this.OnFileTransferProgressEventHandler?.Invoke(this, FileTransferFlag.Transfering, remoteFileName, fileStream.Length, responsed.FileSize);
            }

            this.OnFileTransferProgressEventHandler?.Invoke(this, FileTransferFlag.End, remoteFileName, fileStream.Length, responsed.FileSize);

            fileStream.Close();
        }