Example #1
0
        /// <summary>
        /// Opens the specified file for appending. Please call GetReply() after you have successfully transfered the file to read the "OK" command sent by the server and prevent stale data on the socket.
        /// </summary>
        /// <param name="path">The full or relative path to the file to be opened</param>
        /// <param name="type">ASCII/Binary</param>
        /// <returns>A stream for writing to the file on the server</returns>
        /// <example><code source="..\Examples\OpenAppend.cs" lang="cs" /></example>
        public virtual Stream OpenAppend(string path, FtpDataType type)
        {
            FtpTrace.WriteFunc("OpenAppend", new object[] { path, type });

            FtpClient     client = null;
            FtpDataStream stream = null;
            long          length = 0;

            lock (m_lock) {
                if (m_threadSafeDataChannels)
                {
                    client = CloneConnection();
                    client.Connect();
                    client.SetWorkingDirectory(GetWorkingDirectory());
                }
                else
                {
                    client = this;
                }

                client.SetDataType(type);
                length = client.GetFileSize(path);
                stream = client.OpenDataStream(("APPE " + path.GetFtpPath()), 0);

                if (length > 0 && stream != null)
                {
                    stream.SetLength(length);
                    stream.SetPosition(length);
                }
            }

            return(stream);
        }
Example #2
0
        /// <summary>
        /// Opens the specified file for reading
        /// </summary>
        /// <param name="path">The full or relative path of the file</param>
        /// <param name="type">ASCII/Binary</param>
        /// <param name="restart">Resume location</param>
        /// <returns>A stream for reading the file on the server</returns>
        /// <example><code source="..\Examples\OpenRead.cs" lang="cs" /></example>
        public virtual Stream OpenRead(string path, FtpDataType type, long restart)
        {
            // verify args
            if (path.IsBlank())
            {
                throw new ArgumentException("Required parameter is null or blank.", "path");
            }

            FtpTrace.WriteFunc("OpenRead", new object[] { path, type, restart });

            FtpClient     client = null;
            FtpDataStream stream = null;
            long          length = 0;

#if !CORE14
            lock (m_lock) {
#endif
            if (m_threadSafeDataChannels)
            {
                client = CloneConnection();
                client.Connect();
                client.SetWorkingDirectory(GetWorkingDirectory());
            }
            else
            {
                client = this;
            }

            client.SetDataType(type);
            length = client.GetFileSize(path);
            stream = client.OpenDataStream(("RETR " + path.GetFtpPath()), restart);
#if !CORE14
        }
#endif

            if (stream != null)
            {
                if (length > 0)
                {
                    stream.SetLength(length);
                }

                if (restart > 0)
                {
                    stream.SetPosition(restart);
                }
            }

            return(stream);
        }
Example #3
0
        /// <summary>
        /// Opens the specified file for writing. Please call GetReply() after you have successfully transfered the file to read the "OK" command sent by the server and prevent stale data on the socket.
        /// </summary>
        /// <param name="path">Full or relative path of the file</param>
        /// <param name="type">ASCII/Binary</param>
        /// <param name="checkIfFileExists">Only set this to false if you are SURE that the file does not exist. If true, it reads the file size and saves it into the stream length.</param>
        /// <returns>A stream for writing to the file on the server</returns>
        /// <example><code source="..\Examples\OpenWrite.cs" lang="cs" /></example>
        public virtual Stream OpenWrite(string path, FtpDataType type, bool checkIfFileExists)
        {
            // verify args
            if (path.IsBlank())
            {
                throw new ArgumentException("Required parameter is null or blank.", "path");
            }

            FtpTrace.WriteFunc("OpenWrite", new object[] { path, type });

            FtpClient client     = null;
            FtpDataStream stream = null;
            long length          = 0;

#if !CORE14
            lock (m_lock) {
#endif
            if (m_threadSafeDataChannels)
            {
                client = CloneConnection();
                client.Connect();
                client.SetWorkingDirectory(GetWorkingDirectory());
            }
            else
            {
                client = this;
            }

            client.SetDataType(type);
            length = checkIfFileExists ? client.GetFileSize(path) : 0;
            stream = client.OpenDataStream(("STOR " + path.GetFtpPath()), 0);

            if (length > 0 && stream != null)
            {
                stream.SetLength(length);
            }
#if !CORE14
        }
#endif

            return(stream);
        }
        /// <summary>
        /// Transfers a file from the source FTP Server to the destination FTP Server via the FXP protocol
        /// </summary>
        private bool TransferFileFXPInternal(string sourcePath, FtpClient remoteClient, string remotePath, bool createRemoteDir, FtpRemoteExists existsMode,
                                             Action <FtpProgress> progress, FtpProgress metaProgress)
        {
            FtpReply reply;
            long     offset     = 0;
            bool     fileExists = false;
            long     fileSize   = 0;

            var ftpFxpSession = OpenPassiveFXPConnection(remoteClient, progress != null);

            if (ftpFxpSession != null)
            {
                try {
                    ftpFxpSession.SourceServer.ReadTimeout = (int)TimeSpan.FromMinutes(30.0).TotalMilliseconds;
                    ftpFxpSession.TargetServer.ReadTimeout = (int)TimeSpan.FromMinutes(30.0).TotalMilliseconds;


                    // check if the file exists, and skip, overwrite or append
                    if (existsMode == FtpRemoteExists.AppendNoCheck)
                    {
                        offset = remoteClient.GetFileSize(remotePath);
                        if (offset == -1)
                        {
                            offset = 0;                             // start from the beginning
                        }
                    }
                    else
                    {
                        fileExists = remoteClient.FileExists(remotePath);

                        switch (existsMode)
                        {
                        case FtpRemoteExists.Skip:

                            if (fileExists)
                            {
                                LogStatus(FtpTraceLevel.Info, "Skip is selected => Destination file exists => skipping");

                                //Fix #413 - progress callback isn't called if the file has already been uploaded to the server
                                //send progress reports
                                if (progress != null)
                                {
                                    progress(new FtpProgress(100.0, 0, 0, TimeSpan.FromSeconds(0), sourcePath, remotePath, metaProgress));
                                }

                                return(true);
                            }

                            break;

                        case FtpRemoteExists.Overwrite:

                            if (fileExists)
                            {
                                remoteClient.DeleteFile(remotePath);
                            }

                            break;

                        case FtpRemoteExists.Append:

                            if (fileExists)
                            {
                                offset = remoteClient.GetFileSize(remotePath);
                                if (offset == -1)
                                {
                                    offset = 0;                                             // start from the beginning
                                }
                            }

                            break;
                        }
                    }

                    fileSize = GetFileSize(sourcePath);

                    // ensure the remote dir exists .. only if the file does not already exist!
                    if (createRemoteDir && !fileExists)
                    {
                        var dirname = remotePath.GetFtpDirectoryName();
                        if (!remoteClient.DirectoryExists(dirname))
                        {
                            remoteClient.CreateDirectory(dirname);
                        }
                    }

                    if (offset == 0 && existsMode != FtpRemoteExists.AppendNoCheck)
                    {
                        // send command to tell the source server to 'send' the file to the destination server
                        if (!(reply = ftpFxpSession.SourceServer.Execute($"RETR {sourcePath}")).Success)
                        {
                            throw new FtpCommandException(reply);
                        }

                        //Instruct destination server to store the file
                        if (!(reply = ftpFxpSession.TargetServer.Execute($"STOR {remotePath}")).Success)
                        {
                            throw new FtpCommandException(reply);
                        }
                    }
                    else
                    {
                        //tell source server to restart / resume
                        if (!(reply = ftpFxpSession.SourceServer.Execute($"REST {offset}")).Success)
                        {
                            throw new FtpCommandException(reply);
                        }

                        // send command to tell the source server to 'send' the file to the destination server
                        if (!(reply = ftpFxpSession.SourceServer.Execute($"RETR {sourcePath}")).Success)
                        {
                            throw new FtpCommandException(reply);
                        }

                        //Instruct destination server to append the file
                        if (!(reply = ftpFxpSession.TargetServer.Execute($"APPE {remotePath}")).Success)
                        {
                            throw new FtpCommandException(reply);
                        }
                    }

                    var  transferStarted = DateTime.Now;
                    long lastSize        = 0;

                    var sourceFXPTransferReply      = ftpFxpSession.SourceServer.GetReply();
                    var destinationFXPTransferReply = ftpFxpSession.TargetServer.GetReply();

                    // while the transfer is not complete
                    while (!sourceFXPTransferReply.Success || !destinationFXPTransferReply.Success)
                    {
                        // send progress reports every 1 second
                        if (ftpFxpSession.ProgressServer != null)
                        {
                            // send progress reports
                            if (progress != null && fileSize != -1)
                            {
                                offset = ftpFxpSession.ProgressServer.GetFileSize(remotePath);

                                if (offset != -1 && lastSize <= offset)
                                {
                                    long bytesProcessed = offset - lastSize;
                                    lastSize = offset;
                                    ReportProgress(progress, fileSize, offset, bytesProcessed, DateTime.Now - transferStarted, sourcePath, remotePath, metaProgress);
                                }
                            }
                        }
#if CORE14
                        Task.Delay(FXPProgressInterval);
#else
                        Thread.Sleep(FXPProgressInterval);
#endif
                    }

                    FtpTrace.WriteLine(FtpTraceLevel.Info, $"FXP transfer of file {sourcePath} has completed");

                    Noop();
                    remoteClient.Noop();

                    ftpFxpSession.Dispose();

                    return(true);
                }

                // Fix: catch all exceptions and dispose off the FTP clients if one occurs
                catch (Exception ex) {
                    ftpFxpSession.Dispose();
                    throw ex;
                }
            }
            else
            {
                FtpTrace.WriteLine(FtpTraceLevel.Error, "Failed to open FXP passive Connection");
                return(false);
            }
        }
Example #5
0
 /// <summary>
 /// 获取文件大小
 /// </summary>
 /// <param name="file">服务器文件</param>
 /// <returns></returns>
 public long GetFileSize(string file)
 {
     return(ftp.GetFileSize(file));
 }