Example #1
0
 public TaskInfoUI(FileUploadingInfo fui)
 {
     IsDownloadTask = false;
     FUI            = fui;
     FUI.FTPUploadingInfoNotifications += (FileUploadingInfo source, string[] msgs) => {
         if (msgs.Length > 0)
         {
             Message = msgs[0];
         }
         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Progress"));
         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("ProgressMsg"));
         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsIndeterminate"));
         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("FileSize"));
         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Speed"));
         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("TimeRemaining"));
         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Status"));
     };
     stopwatch.Start();
 }
Example #2
0
        private async void UploadLocalFile(string localFilePath, string localFileName, string remoteFilePath, string remoteFileName)
        {
            if (connectionStatus != ConnectionStatus.Connected)
            {
                return;
            }
            var        fui  = new FileUploadingInfo(ftpService.Server, localFilePath, localFileName, remoteFilePath, remoteFileName);
            TaskInfoUI tiUI = new TaskInfoUI(fui);

            fui.Tag          = tiUI;
            tiUI.tokenSource = new CancellationTokenSource();
            taskInfoList.Add(tiUI);
            await ftpService.UploadFile(fui, tiUI.tokenSource.Token, DefaultFTPTaskErrorHandler);

            if (fui.IsFinished)
            {
                RefreshRemoteInfo();
            }
        }
Example #3
0
 public Task UploadFile(FileUploadingInfo fileUploadingInfo, CancellationToken token, FTPTaskErrorHandler ftpTaskErrorHandler = null)
 {
     return(Task.Run(() =>
     {
         lock (fileUploadingInfo)
         {
             if (fileUploadingInfo.IsFinished)
             {
                 return;
             }
             FTPConnection ftpConnection = null;
             try
             {
                 ftpConnection = CreateConnection(fileUploadingInfo.serverInfo);
                 Utils.WriteDebugInfo(ftpConnection.connectionName, "用于上传文件的连接已建立。\r\nFileUploadingInfo: " + fileUploadingInfo.ToString());
                 ftpConnection.UploadFile(fileUploadingInfo, token);
                 ftpConnection.Close();
                 fileUploadingInfo.Close();
                 fileUploadingInfo.IsFinished = true;
                 Utils.WriteDebugInfo(ftpConnection.connectionName, "操作已完成,连接主动断开。");
             }
             catch (OperationCanceledException)
             {
                 ftpConnection?.Close();
                 if (ftpConnection != null)
                 {
                     Utils.WriteDebugInfo(ftpConnection.connectionName, "操作被用户取消,连接已断开。");
                 }
             }
             catch (FTPResponseException ex)
             {
                 ftpTaskErrorHandler?.Invoke(ex, fileUploadingInfo.Tag);
                 ftpConnection?.Close();
                 if (ftpConnection != null)
                 {
                     Utils.WriteDebugInfo(ftpConnection.connectionName, "由于发生了不可恢复的异常,连接已断开。" + " FTPResponseException: " + ex.Message);
                 }
             }
         }
     }));
 }
Example #4
0
        public void UploadFile(FileUploadingInfo fui, CancellationToken token)
        {
            try
            {
                ChangeCurrentWorkingDirectory(fui.RemotePath);

                string localfile  = fui.LocalPath + (fui.LocalPath.EndsWith("\\") ? "" : "\\") + fui.LocalFileName;
                string remotefile = fui.RemotePath + (fui.RemotePath.EndsWith("/") ? "" : "/") + fui.RemoteFileName;

                if (fui.UploadedBytes == 0)
                {
                    var size = GetFileSize(remotefile);
                    if (size != -1)
                    {
                        throw new FTPResponseException("远程文件已存在");
                    }
                }
                else
                {
                    long size       = -1;
                    int  retryCount = 0;
                    // Note: Windows Server IIS FTP会锁住未完全上传的文件,解锁时机未知,需要重试等待
                    while (size == -1 && retryCount <= 3)
                    {
                        retryCount++;
                        Utils.WriteDebugInfo(connectionName, "恢复上传:正在尝试获取文件大小,尝试次数:" + retryCount);
                        size = GetFileSize(remotefile);
                        Thread.Sleep(500);
                    }
                    if (size == -1)
                    {
                        throw new FTPResponseException("无法获取远程文件大小,上传程序无法确定REST位置,请稍后重试或重新上传。");
                    }
                    if (size != fui.UploadedBytes)
                    {
                        if (size < fui.UploadedBytes)
                        {
                            fui.Notify("Remote File Size小于UploadedBytes,将从Remote Size恢复下载,建议检查文件正确性。");
                            fui.UploadedBytes = size;
                        }
                        else
                        {
                            throw new FTPResponseException("Remote File Size大于UploadedBytes,文件很可能已被其他程序修改,请重新上传。");
                        }
                    }
                }
                SendCommand("CWD " + remotefile);
                Dictionary <int, string> response = null;
                try
                {
                    response = ReceiveResponse(250);
                } catch (FTPResponseException) { }
                if (response != null)
                {
                    throw new FTPResponseException("同名远程文件夹已存在");
                }

                FileInfo fileInfo = new FileInfo(localfile);
                fui.FileSize = fileInfo.Length;

                EnterPassiveMode();
                if (fui.UploadedBytes > 0)
                {
                    fui.LocalFileStream.Seek(fui.UploadedBytes, SeekOrigin.Begin);
                    SendCommand("REST " + fui.UploadedBytes);
                    try
                    {
                        var message = ReceiveResponse(300, 350);
                        if (message == null)
                        {
                            throw new FTPResponseException();
                        }
                    }
                    catch (FTPResponseException)
                    {
                        // 服务器可能不支持REST指令
                        fui.Notify("服务器不支持断点续传,从0开始上传");
                        fui.UploadedBytes = 0;
                    }
                }
                else
                {
                    fui.LocalFileStream = File.Open(localfile, FileMode.Open, FileAccess.Read, FileShare.Read);
                    SendCommand("ALLO " + fui.FileSize);
                    var rp = ReceiveRawResponse();
                }

                dataSocket.SendBufferSize = 1024 * 1024;
                SendCommand("STOR " + remotefile);
                // 等待服务器响应 125 Data connection already open 或 150 about to open data connection
                var msgs = ReceiveResponse(125, 150);
                if (msgs == null)
                {
                    throw new FTPResponseException("远程主机对于 STOR 命令没有预期的响应或超时");
                }
                byte[] buf = new byte[1024 * 1024];
                while (fui.UploadedBytes < fui.FileSize)
                {
                    token.ThrowIfCancellationRequested();
                    int total = fui.LocalFileStream.Read(buf, 0, buf.Length);
                    var sent  = dataSocket.Send(buf, 0, total, SocketFlags.None);
                    if (sent != total)
                    {
                        throw new ApplicationException("sent!=total");
                    }
                    if (dataSocket.Connected == false)
                    {
                        throw new FTPResponseException("远程主机断开连接");
                    }
                    fui.UploadedBytes += sent;
                }
                fui.LocalFileStream.Close();
                dataSocket.Shutdown(SocketShutdown.Send);
                dataSocket.Disconnect(true);
            }
            catch (OperationCanceledException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new FTPResponseException(ex.Message);
            }
        }