FTP上傳類FTP上傳C#類

jopen 12年前發布 | 3K 次閱讀

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Globalization;
using System.Text.RegularExpressions;
namespace WebBaseLib
{
    /// <summary>
    /// FTP處理操作類
    /// 功能:
    /// 下載文件
    /// 上傳文件
    /// 上傳文件的進度信息
    /// 下載文件的進度信息
    /// 刪除文件
    /// 列出文件
    /// 列出目錄
    /// 進入子目錄
    /// 退出當前目錄返回上一層目錄
    /// 判斷遠程文件是否存在
    /// 判斷遠程文件是否存在
    /// 刪除遠程文件
/// 建立目錄 /// 刪除目錄 /// 文件(目錄)改名

/// </summary>
/// <remarks>
/// 創建人:南瘋
/// 創建時間:2007年4月28日
/// </remarks>
#region 文件信息結構
public struct FileStruct
{
    public string Flags;
    public string Owner;
    public string Group;
    public bool IsDirectory;
    public DateTime CreateTime;
    public string Name;
}
public enum FileListStyle
{
    UnixStyle,
    WindowsStyle,
    Unknown
}
#endregion
public class NewFtp
{
    #region 屬性信息
    /// <summary>
    /// FTP請求對象
    /// </summary>
    FtpWebRequest Request = null;
    /// <summary>
    /// FTP響應對象
    /// </summary>
    FtpWebResponse Response = null;
    /// <summary>
    /// FTP服務器地址
    /// </summary>
    private Uri _Uri;
    /// <summary>
    /// FTP服務器地址
    /// </summary>
    public Uri Uri
    {
        get
        {
            if( _DirectoryPath == "/" )
            {
                return _Uri;
            }
            else
            {
                string strUri = _Uri.ToString();
                if( strUri.EndsWith( "/" ) )
                {
                    strUri = strUri.Substring( 0, strUri.Length - 1 );
                }
                return new Uri( strUri + this.DirectoryPath );
            }
        }
        set
        {
            if( value.Scheme != Uri.UriSchemeFtp )
            {
                throw new Exception( "Ftp 地址格式錯誤!" );
            }
            _Uri = new Uri( value.GetLeftPart( UriPartial.Authority ) );
            _DirectoryPath = value.AbsolutePath;
            if( !_DirectoryPath.EndsWith( "/" ) )
            {
                _DirectoryPath += "/";
            }
        }
    }

    /// <summary>
    /// 當前工作目錄
    /// </summary>
    private string _DirectoryPath;

    /// <summary>
    /// 當前工作目錄
    /// </summary>
    public string DirectoryPath
    {
        get
        {
            return _DirectoryPath;
        }
        set
        {
            _DirectoryPath = value;
        }
    }

    /// <summary>
    /// FTP登錄用戶
    /// </summary>
    private string _UserName;
    /// <summary>
    /// FTP登錄用戶
    /// </summary>
    public string UserName
    {
        get
        {
            return _UserName;
        }
        set
        {
            _UserName = value;
        }
    }

    /// <summary>
    /// 錯誤信息
    /// </summary>
    private string _ErrorMsg;
    /// <summary>
    /// 錯誤信息
    /// </summary>
    public string ErrorMsg
    {
        get
        {
            return _ErrorMsg;
        }
        set
        {
            _ErrorMsg = value;
        }
    }

    /// <summary>
    /// FTP登錄密碼
    /// </summary>
    private string _Password;
    /// <summary>
    /// FTP登錄密碼
    /// </summary>
    public string Password
    {
        get
        {
            return _Password;
        }
        set
        {
            _Password = value;
        }
    }

    /// <summary>
    /// 連接FTP服務器的代理服務
    /// </summary>
    private WebProxy _Proxy = null;
    /// <summary>
    /// 連接FTP服務器的代理服務
    /// </summary>
    public WebProxy Proxy
    {
        get
        {
            return _Proxy;
        }
        set
        {
            _Proxy = value;
        }
    }

    /// <summary>
    /// 是否需要刪除臨時文件
    /// </summary>
    private bool _isDeleteTempFile = false;
    /// <summary>
    /// 異步上傳所臨時生成的文件
    /// </summary>
    private string _UploadTempFile = "";
    #endregion
    #region 事件
    public delegate void De_DownloadProgressChanged( object sender, DownloadProgressChangedEventArgs e );
    public delegate void De_DownloadDataCompleted( object sender, System.ComponentModel.AsyncCompletedEventArgs e );
    public delegate void De_UploadProgressChanged( object sender, UploadProgressChangedEventArgs e );
    public delegate void De_UploadFileCompleted( object sender, UploadFileCompletedEventArgs e );

    /// <summary>
    /// 異步下載進度發生改變觸發的事件
    /// </summary>
    public event De_DownloadProgressChanged DownloadProgressChanged;
    /// <summary>
    /// 異步下載文件完成之后觸發的事件
    /// </summary>
    public event De_DownloadDataCompleted DownloadDataCompleted;
    /// <summary>
    /// 異步上傳進度發生改變觸發的事件
    /// </summary>
    public event De_UploadProgressChanged UploadProgressChanged;
    /// <summary>
    /// 異步上傳文件完成之后觸發的事件
    /// </summary>
    public event De_UploadFileCompleted UploadFileCompleted;
    #endregion
    #region 構造析構函數
    /// <summary>
    /// 構造函數
    /// </summary>
    /// <param name="FtpUri">FTP地址</param>
    /// <param name="strUserName">登錄用戶名</param>
    /// <param name="strPassword">登錄密碼</param>
    public NewFtp( Uri FtpUri, string strUserName, string strPassword )
    {
        this._Uri = new Uri( FtpUri.GetLeftPart( UriPartial.Authority ) );
        _DirectoryPath = FtpUri.AbsolutePath;
        if( !_DirectoryPath.EndsWith( "/" ) )
        {
            _DirectoryPath += "/";
        }
        this._UserName = strUserName;
        this._Password = strPassword;
        this._Proxy = null;
    }
    /// <summary>
    /// 構造函數
    /// </summary>
    /// <param name="FtpUri">FTP地址</param>
    /// <param name="strUserName">登錄用戶名</param>
    /// <param name="strPassword">登錄密碼</param>
    /// <param name="objProxy">連接代理</param>
    public NewFtp( Uri FtpUri, string strUserName, string strPassword, WebProxy objProxy )
    {
        this._Uri = new Uri( FtpUri.GetLeftPart( UriPartial.Authority ) );
        _DirectoryPath = FtpUri.AbsolutePath;
        if( !_DirectoryPath.EndsWith( "/" ) )
        {
            _DirectoryPath += "/";
        }
        this._UserName = strUserName;
        this._Password = strPassword;
        this._Proxy = objProxy;
    }
    /// <summary>
    /// 構造函數
    /// </summary>
    public NewFtp()
    {
        this._UserName = "anonymous";  //匿名用戶
        this._Password = "@anonymous";
        this._Uri = null;
        this._Proxy = null;
    }

    /// <summary>
    /// 析構函數
    /// </summary>
    ~NewFtp()
    {
        if( Response != null )
        {
            Response.Close();
            Response = null;
        }
        if( Request != null )
        {
            Request.Abort();
            Request = null;
        }
    }
    #endregion
    #region 建立連接
    /// <summary>
    /// 建立FTP鏈接,返回響應對象
    /// </summary>
    /// <param name="uri">FTP地址</param>
    /// <param name="FtpMathod">操作命令</param>
    private FtpWebResponse Open( Uri uri, string FtpMathod )
    {
        try
        {
            Request = ( FtpWebRequest ) WebRequest.Create( uri );
            Request.Method = FtpMathod;
            Request.UseBinary = true;
            Request.Credentials = new NetworkCredential( this.UserName, this.Password );
            if( this.Proxy != null )
            {
                Request.Proxy = this.Proxy;
            }
            return ( FtpWebResponse ) Request.GetResponse();
        }
        catch( Exception ep )
        {
            ErrorMsg = ep.ToString();
            throw ep;
        }
    }
    /// <summary>
    /// 建立FTP鏈接,返回請求對象
    /// </summary>
    /// <param name="uri">FTP地址</param>
    /// <param name="FtpMathod">操作命令</param>
    private FtpWebRequest OpenRequest( Uri uri, string FtpMathod )
    {
        try
        {
            Request = ( FtpWebRequest ) WebRequest.Create( uri );
            Request.Method = FtpMathod;
            Request.UseBinary = true;
            Request.Credentials = new NetworkCredential( this.UserName, this.Password );
            if( this.Proxy != null )
            {
                Request.Proxy = this.Proxy;
            }
            return Request;
        }
        catch( Exception ep )
        {
            ErrorMsg = ep.ToString();
            throw ep;
        }
    }
    #endregion
    #region 下載文件

    /// <summary>
    /// 從FTP服務器下載文件,使用與遠程文件同名的文件名來保存文件
    /// </summary>
    /// <param name="RemoteFileName">遠程文件名</param>
    /// <param name="LocalPath">本地路徑</param>

    public bool DownloadFile( string RemoteFileName, string LocalPath )
    {
        return DownloadFile( RemoteFileName, LocalPath, RemoteFileName );
    }
    /// <summary>
    /// 從FTP服務器下載文件,指定本地路徑和本地文件名
    /// </summary>
    /// <param name="RemoteFileName">遠程文件名</param>
    /// <param name="LocalPath">本地路徑</param>
    /// <param name="LocalFilePath">保存文件的本地路徑,后面帶有""</param>
    /// <param name="LocalFileName">保存本地的文件名</param>
    public bool DownloadFile( string RemoteFileName, string LocalPath, string LocalFileName )
    {
        byte[] bt = null;
        try
        {
            if( !IsValidFileChars( RemoteFileName ) || !IsValidFileChars( LocalFileName ) || !IsValidPathChars( LocalPath ) )
            {
                throw new Exception( "非法文件名或目錄名!" );
            }
            if( !Directory.Exists( LocalPath ) )
            {
                throw new Exception( "本地文件路徑不存在!" );
            }

            string LocalFullPath = Path.Combine( LocalPath, LocalFileName );
            if( File.Exists( LocalFullPath ) )
            {
                throw new Exception( "當前路徑下已經存在同名文件!" );
            }
            bt = DownloadFile( RemoteFileName );
            if( bt != null )
            {
                FileStream stream = new FileStream( LocalFullPath, FileMode.Create );
                stream.Write( bt, 0, bt.Length );
                stream.Flush();
                stream.Close();
                return true;
            }
            else
            {
                return false;
            }
        }
        catch( Exception ep )
        {
            ErrorMsg = ep.ToString();
            throw ep;
        }
    }

    /// <summary>
    /// 從FTP服務器下載文件,返回文件二進制數據
    /// </summary>
    /// <param name="RemoteFileName">遠程文件名</param>
    public byte[] DownloadFile( string RemoteFileName )
    {
        try
        {
            if( !IsValidFileChars( RemoteFileName ) )
            {
                throw new Exception( "非法文件名或目錄名!" );
            }
            Response = Open( new Uri( this.Uri.ToString() + RemoteFileName ), WebRequestMethods.Ftp.DownloadFile );
            Stream Reader = Response.GetResponseStream();

            MemoryStream mem = new MemoryStream( 1024 * 500 );
            byte[] buffer = new byte[ 1024 ];
            int bytesRead = 0;
            int TotalByteRead = 0;
            while( true )
            {
                bytesRead = Reader.Read( buffer, 0, buffer.Length );
                TotalByteRead += bytesRead;
                if( bytesRead == 0 )
                    break;
                mem.Write( buffer, 0, bytesRead );
            }
            if( mem.Length > 0 )
            {
                return mem.ToArray();
            }
            else
            {
                return null;
            }
        }
        catch( Exception ep )
        {
            ErrorMsg = ep.ToString();
            throw ep;
        }
    }
    #endregion
    #region 異步下載文件
    /// <summary>
    /// 從FTP服務器異步下載文件,指定本地路徑和本地文件名
    /// </summary>
    /// <param name="RemoteFileName">遠程文件名</param>       
    /// <param name="LocalPath">保存文件的本地路徑,后面帶有""</param>
    /// <param name="LocalFileName">保存本地的文件名</param>
    public void DownloadFileAsync( string RemoteFileName, string LocalPath, string LocalFileName )
    {
        byte[] bt = null;
        try
        {
            if( !IsValidFileChars( RemoteFileName ) || !IsValidFileChars( LocalFileName ) || !IsValidPathChars( LocalPath ) )
            {
                throw new Exception( "非法文件名或目錄名!" );
            }
            if( !Directory.Exists( LocalPath ) )
            {
                throw new Exception( "本地文件路徑不存在!" );
            }

            string LocalFullPath = Path.Combine( LocalPath, LocalFileName );
            if( File.Exists( LocalFullPath ) )
            {
                throw new Exception( "當前路徑下已經存在同名文件!" );
            }
            DownloadFileAsync( RemoteFileName, LocalFullPath );

        }
        catch( Exception ep )
        {
            ErrorMsg = ep.ToString();
            throw ep;
        }
    }

    /// <summary>
    /// 從FTP服務器異步下載文件,指定本地完整路徑文件名
    /// </summary>
    /// <param name="RemoteFileName">遠程文件名</param>
    /// <param name="LocalFullPath">本地完整路徑文件名</param>
    public void DownloadFileAsync( string RemoteFileName, string LocalFullPath )
    {
        try
        {
            if( !IsValidFileChars( RemoteFileName ) )
            {
                throw new Exception( "非法文件名或目錄名!" );
            }
            if( File.Exists( LocalFullPath ) )
            {
                throw new Exception( "當前路徑下已經存在同名文件!" );
            }
            MyWebClient client = new MyWebClient();

            client.DownloadProgressChanged += new DownloadProgressChangedEventHandler( client_DownloadProgressChanged );
            client.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler( client_DownloadFileCompleted );
            client.Credentials = new NetworkCredential( this.UserName, this.Password );
            if( this.Proxy != null )
            {
                client.Proxy = this.Proxy;
            }
            client.DownloadFileAsync( new Uri( this.Uri.ToString() + RemoteFileName ), LocalFullPath );
        }
        catch( Exception ep )
        {
            ErrorMsg = ep.ToString();
            throw ep;
        }
    }

    /// <summary>
    /// 異步下載文件完成之后觸發的事件
    /// </summary>
    /// <param name="sender">下載對象</param>
    /// <param name="e">數據信息對象</param>
    void client_DownloadFileCompleted( object sender, System.ComponentModel.AsyncCompletedEventArgs e )
    {
        if( DownloadDataCompleted != null )
        {
            DownloadDataCompleted( sender, e );
        }
    }

    /// <summary>
    /// 異步下載進度發生改變觸發的事件
    /// </summary>
    /// <param name="sender">下載對象</param>
    /// <param name="e">進度信息對象</param>
    void client_DownloadProgressChanged( object sender, DownloadProgressChangedEventArgs e )
    {
        if( DownloadProgressChanged != null )
        {
            DownloadProgressChanged( sender, e );
        }
    }
    #endregion
    #region 上傳文件
    /// <summary>
    /// 上傳文件到FTP服務器
    /// </summary>
    /// <param name="LocalFullPath">本地帶有完整路徑的文件名</param>
    public bool UploadFile( string LocalFullPath )
    {
        return UploadFile( LocalFullPath, Path.GetFileName( LocalFullPath ), false );
    }
    /// <summary>
    /// 上傳文件到FTP服務器
    /// </summary>
    /// <param name="LocalFullPath">本地帶有完整路徑的文件</param>
    /// <param name="OverWriteRemoteFile">是否覆蓋遠程服務器上面同名的文件</param>
    public bool UploadFile( string LocalFullPath, bool OverWriteRemoteFile )
    {
        return UploadFile( LocalFullPath, Path.GetFileName( LocalFullPath ), OverWriteRemoteFile );
    }
    /// <summary>
    /// 上傳文件到FTP服務器
    /// </summary>
    /// <param name="LocalFullPath">本地帶有完整路徑的文件</param>
    /// <param name="RemoteFileName">要在FTP服務器上面保存文件名</param>
    public bool UploadFile( string LocalFullPath, string RemoteFileName )
    {
        return UploadFile( LocalFullPath, RemoteFileName, false );
    }
    /// <summary>
    /// 上傳文件到FTP服務器
    /// </summary>
    /// <param name="LocalFullPath">本地帶有完整路徑的文件名</param>
    /// <param name="RemoteFileName">要在FTP服務器上面保存文件名</param>
    /// <param name="OverWriteRemoteFile">是否覆蓋遠程服務器上面同名的文件</param>
    public bool UploadFile( string LocalFullPath, string RemoteFileName, bool OverWriteRemoteFile )
    {
        try
        {
            if( !IsValidFileChars( RemoteFileName ) || !IsValidFileChars( Path.GetFileName( LocalFullPath ) ) || !IsValidPathChars( Path.GetDirectoryName( LocalFullPath ) ) )
            {
                throw new Exception( "非法文件名或目錄名!" );
            }
            if( File.Exists( LocalFullPath ) )
            {
                FileStream Stream = new FileStream( LocalFullPath, FileMode.Open, FileAccess.Read );
                byte[] bt = new byte[ Stream.Length ];
                Stream.Read( bt, 0, ( Int32 ) Stream.Length );   //注意,因為Int32的最大限制,最大上傳文件只能是大約2G多一點
                Stream.Close();
                return UploadFile( bt, RemoteFileName, OverWriteRemoteFile );
            }
            else
            {
                throw new Exception( "本地文件不存在!" );
            }
        }
        catch( Exception ep )
        {
            ErrorMsg = ep.ToString();
            throw ep;
        }
    }
    /// <summary>
    /// 上傳文件到FTP服務器
    /// </summary>
    /// <param name="FileBytes">上傳的二進制數據</param>
    /// <param name="RemoteFileName">要在FTP服務器上面保存文件名</param>
    public bool UploadFile( byte[] FileBytes, string RemoteFileName )
    {
        if( !IsValidFileChars( RemoteFileName ) )
        {
            throw new Exception( "非法文件名或目錄名!" );
        }
        return UploadFile( FileBytes, RemoteFileName, false );
    }
    /// <summary>
    /// 上傳文件到FTP服務器
    /// </summary>
    /// <param name="FileBytes">文件二進制內容</param>
    /// <param name="RemoteFileName">要在FTP服務器上面保存文件名</param>
    /// <param name="OverWriteRemoteFile">是否覆蓋遠程服務器上面同名的文件</param>
    public bool UploadFile( byte[] FileBytes, string RemoteFileName, bool OverWriteRemoteFile )
    {
        try
        {
            if( !IsValidFileChars( RemoteFileName ) )
            {
                throw new Exception( "非法文件名!" );
            }
            if( !OverWriteRemoteFile && FileExist( RemoteFileName ) )
            {
                throw new Exception( "FTP服務上面已經存在同名文件!" );
            }
            Response = Open( new Uri( this.Uri.ToString() + RemoteFileName ), WebRequestMethods.Ftp.UploadFile );
            Stream requestStream = Request.GetRequestStream();
            MemoryStream mem = new MemoryStream( FileBytes );

            byte[] buffer = new byte[ 1024 ];
            int bytesRead = 0;
            int TotalRead = 0;
            while( true )
            {
                bytesRead = mem.Read( buffer, 0, buffer.Length );
                if( bytesRead == 0 )
                    break;
                TotalRead += bytesRead;
                requestStream.Write( buffer, 0, bytesRead );
            }
            requestStream.Close();
            Response = ( FtpWebResponse ) Request.GetResponse();
            mem.Close();
            mem.Dispose();
            FileBytes = null;
            return true;
        }
        catch( Exception ep )
        {
            ErrorMsg = ep.ToString();
            throw ep;
        }
    }
    #endregion
    #region 異步上傳文件
    /// <summary>
    /// 異步上傳文件到FTP服務器
    /// </summary>
    /// <param name="LocalFullPath">本地帶有完整路徑的文件名</param>
    public void UploadFileAsync( string LocalFullPath )
    {
        UploadFileAsync( LocalFullPath, Path.GetFileName( LocalFullPath ), false );
    }
    /// <summary>
    /// 異步上傳文件到FTP服務器
    /// </summary>
    /// <param name="LocalFullPath">本地帶有完整路徑的文件</param>
    /// <param name="OverWriteRemoteFile">是否覆蓋遠程服務器上面同名的文件</param>
    public void UploadFileAsync( string LocalFullPath, bool OverWriteRemoteFile )
    {
        UploadFileAsync( LocalFullPath, Path.GetFileName( LocalFullPath ), OverWriteRemoteFile );
    }
    /// <summary>
    /// 異步上傳文件到FTP服務器
    /// </summary>
    /// <param name="LocalFullPath">本地帶有完整路徑的文件</param>
    /// <param name="RemoteFileName">要在FTP服務器上面保存文件名</param>
    public void UploadFileAsync( string LocalFullPath, string RemoteFileName )
    {
        UploadFileAsync( LocalFullPath, RemoteFileName, false );
    }
    /// <summary>
    /// 異步上傳文件到FTP服務器
    /// </summary>
    /// <param name="LocalFullPath">本地帶有完整路徑的文件名</param>
    /// <param name="RemoteFileName">要在FTP服務器上面保存文件名</param>
    /// <param name="OverWriteRemoteFile">是否覆蓋遠程服務器上面同名的文件</param>
    public void UploadFileAsync( string LocalFullPath, string RemoteFileName, bool OverWriteRemoteFile )
    {
        try
        {
            if( !IsValidFileChars( RemoteFileName ) || !IsValidFileChars( Path.GetFileName( LocalFullPath ) ) || !IsValidPathChars( Path.GetDirectoryName( LocalFullPath ) ) )
            {
                throw new Exception( "非法文件名或目錄名!" );
            }
            if( !OverWriteRemoteFile && FileExist( RemoteFileName ) )
            {
                throw new Exception( "FTP服務上面已經存在同名文件!" );
            }
            if( File.Exists( LocalFullPath ) )
            {
                MyWebClient client = new MyWebClient();

                client.UploadProgressChanged += new UploadProgressChangedEventHandler( client_UploadProgressChanged );
                client.UploadFileCompleted += new UploadFileCompletedEventHandler( client_UploadFileCompleted );
                client.Credentials = new NetworkCredential( this.UserName, this.Password );
                if( this.Proxy != null )
                {
                    client.Proxy = this.Proxy;
                }
                client.UploadFileAsync( new Uri( this.Uri.ToString() + RemoteFileName ), LocalFullPath );

            }
            else
            {
                throw new Exception( "本地文件不存在!" );
            }
        }
        catch( Exception ep )
        {
            ErrorMsg = ep.ToString();
            throw ep;
        }
    }
    /// <summary>
    /// 異步上傳文件到FTP服務器
    /// </summary>
    /// <param name="FileBytes">上傳的二進制數據</param>
    /// <param name="RemoteFileName">要在FTP服務器上面保存文件名</param>
    public void UploadFileAsync( byte[] FileBytes, string RemoteFileName )
    {
        if( !IsValidFileChars( RemoteFileName ) )
        {
            throw new Exception( "非法文件名或目錄名!" );
        }
        UploadFileAsync( FileBytes, RemoteFileName, false );
    }
    /// <summary>
    /// 異步上傳文件到FTP服務器
    /// </summary>
    /// <param name="FileBytes">文件二進制內容</param>
    /// <param name="RemoteFileName">要在FTP服務器上面保存文件名</param>
    /// <param name="OverWriteRemoteFile">是否覆蓋遠程服務器上面同名的文件</param>
    public void UploadFileAsync( byte[] FileBytes, string RemoteFileName, bool OverWriteRemoteFile )
    {
        try
        {

            if( !IsValidFileChars( RemoteFileName ) )
            {
                throw new Exception( "非法文件名!" );
            }
            if( !OverWriteRemoteFile && FileExist( RemoteFileName ) )
            {
                throw new Exception( "FTP服務上面已經存在同名文件!" );
            }
            string TempPath = System.Environment.GetFolderPath( Environment.SpecialFolder.Templates );
            if( !TempPath.EndsWith( "/" ) )
            {
                TempPath += "/";
            }
            string TempFile = TempPath + Path.GetRandomFileName();
            TempFile = Path.ChangeExtension( TempFile, Path.GetExtension( RemoteFileName ) );
            FileStream Stream = new FileStream( TempFile, FileMode.CreateNew, FileAccess.Write );
            Stream.Write( FileBytes, 0, FileBytes.Length );   //注意,因為Int32的最大限制,最大上傳文件只能是大約2G多一點
            Stream.Flush();
            Stream.Close();
            Stream.Dispose();
            _isDeleteTempFile = true;
            _UploadTempFile = TempFile;
            FileBytes = null;
            UploadFileAsync( TempFile, RemoteFileName, OverWriteRemoteFile );



        }
        catch( Exception ep )
        {
            ErrorMsg = ep.ToString();
            throw ep;
        }
    }

    /// <summary>
    /// 異步上傳文件完成之后觸發的事件
    /// </summary>
    /// <param name="sender">下載對象</param>
    /// <param name="e">數據信息對象</param>
    void client_UploadFileCompleted( object sender, UploadFileCompletedEventArgs e )
    {
        if( _isDeleteTempFile )
        {
            if( File.Exists( _UploadTempFile ) )
            {
                File.SetAttributes( _UploadTempFile, FileAttributes.Normal );
                File.Delete( _UploadTempFile );
            }
            _isDeleteTempFile = false;
        }
        if( UploadFileCompleted != null )
        {
            UploadFileCompleted( sender, e );
        }
    }

    /// <summary>
    /// 異步上傳進度發生改變觸發的事件
    /// </summary>
    /// <param name="sender">下載對象</param>
    /// <param name="e">進度信息對象</param>
    void client_UploadProgressChanged( object sender, UploadProgressChangedEventArgs e )
    {
        if( UploadProgressChanged != null )
        {
            UploadProgressChanged( sender, e );
        }
    }
    #endregion
    #region 列出目錄文件信息
    /// <summary>
    /// 列出FTP服務器上面當前目錄的所有文件和目錄
    /// </summary>
    public FileStruct[] ListFilesAndDirectories()
    {
        Response = Open( this.Uri, WebRequestMethods.Ftp.ListDirectoryDetails );
        StreamReader stream = new StreamReader( Response.GetResponseStream(), Encoding.Default );
        string Datastring = stream.ReadToEnd();
        FileStruct[] list = GetList( Datastring );
        return list;
    }
    /// <summary>
    /// 列出FTP服務器上面當前目錄的所有文件
    /// </summary>
    public FileStruct[] ListFiles()
    {
        FileStruct[] listAll = ListFilesAndDirectories();
        List<FileStruct> listFile = new List<FileStruct>();
        foreach( FileStruct file in listAll )
        {
            if( !file.IsDirectory )
            {
                listFile.Add( file );
            }
        }
        return listFile.ToArray();
    }

    /// <summary>
    /// 列出FTP服務器上面當前目錄的所有的目錄
    /// </summary>
    public FileStruct[] ListDirectories()
    {
        FileStruct[] listAll = ListFilesAndDirectories();
        List<FileStruct> listDirectory = new List<FileStruct>();
        foreach( FileStruct file in listAll )
        {
            if( file.IsDirectory )
            {
                listDirectory.Add( file );
            }
        }
        return listDirectory.ToArray();
    }
    /// <summary>
    /// 獲得文件和目錄列表
    /// </summary>
    /// <param name="datastring">FTP返回的列表字符信息</param>
    private FileStruct[] GetList( string datastring )
    {
        List<FileStruct> myListArray = new List<FileStruct>();
        string[] dataRecords = datastring.Split( '

' ); FileListStyle _directoryListStyle = GuessFileListStyle( dataRecords ); foreach( string s in dataRecords ) { if( _directoryListStyle != FileListStyle.Unknown && s != "" ) { FileStruct f = new FileStruct(); f.Name = ".."; switch( _directoryListStyle ) { case FileListStyle.UnixStyle: f = ParseFileStructFromUnixStyleRecord( s ); break; case FileListStyle.WindowsStyle: f = ParseFileStructFromWindowsStyleRecord( s ); break; } if( !( f.Name == "." || f.Name == ".." ) ) { myListArray.Add( f ); } } } return myListArray.ToArray(); }

    /// <summary>
    /// 從Windows格式中返回文件信息
    /// </summary>
    /// <param name="Record">文件信息</param>
    private FileStruct ParseFileStructFromWindowsStyleRecord( string Record )
    {
        FileStruct f = new FileStruct();
        string processstr = Record.Trim();
        string dateStr = processstr.Substring( 0, 8 );
        processstr = ( processstr.Substring( 8, processstr.Length - 8 ) ).Trim();
        string timeStr = processstr.Substring( 0, 7 );
        processstr = ( processstr.Substring( 7, processstr.Length - 7 ) ).Trim();
        DateTimeFormatInfo myDTFI = new CultureInfo( "en-US", false ).DateTimeFormat;
        myDTFI.ShortTimePattern = "t";
        f.CreateTime = DateTime.Parse( dateStr + " " + timeStr, myDTFI );
        if( processstr.Substring( 0, 5 ) == "<DIR>" )
        {
            f.IsDirectory = true;
            processstr = ( processstr.Substring( 5, processstr.Length - 5 ) ).Trim();
        }
        else
        {
            string[] strs = processstr.Split( new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries );   // true);
            processstr = strs[ 1 ];
            f.IsDirectory = false;
        }
        f.Name = processstr;
        return f;
    }


    /// <summary>
    /// 判斷文件列表的方式Window方式還是Unix方式
    /// </summary>
    /// <param name="recordList">文件信息列表</param>
    private FileListStyle GuessFileListStyle( string[] recordList )
    {
        foreach( string s in recordList )
        {
            if( s.Length > 10
             && Regex.IsMatch( s.Substring( 0, 10 ), "(-|d)(-|r)(-|w)(-|x)(-|r)(-|w)(-|x)(-|r)(-|w)(-|x)" ) )
            {
                return FileListStyle.UnixStyle;
            }
            else if( s.Length > 8
             && Regex.IsMatch( s.Substring( 0, 8 ), "[0-9][0-9]-[0-9][0-9]-[0-9][0-9]" ) )
            {
                return FileListStyle.WindowsStyle;
            }
        }
        return FileListStyle.Unknown;
    }

    /// <summary>
    /// 從Unix格式中返回文件信息
    /// </summary>
    /// <param name="Record">文件信息</param>
    private FileStruct ParseFileStructFromUnixStyleRecord( string Record )
    {
        FileStruct f = new FileStruct();
        string processstr = Record.Trim();
        f.Flags = processstr.Substring( 0, 10 );
        f.IsDirectory = ( f.Flags[ 0 ] == 'd' );
        processstr = ( processstr.Substring( 11 ) ).Trim();
        _cutSubstringFromStringWithTrim( ref processstr, ' ', 0 );   //跳過一部分
        f.Owner = _cutSubstringFromStringWithTrim( ref processstr, ' ', 0 );
        f.Group = _cutSubstringFromStringWithTrim( ref processstr, ' ', 0 );
        _cutSubstringFromStringWithTrim( ref processstr, ' ', 0 );   //跳過一部分
        string yearOrTime = processstr.Split( new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries )[ 2 ];
        if( yearOrTime.IndexOf( ":" ) >= 0 )  //time
        {
            processstr = processstr.Replace( yearOrTime, DateTime.Now.Year.ToString() );
        }
        f.CreateTime = DateTime.Parse( _cutSubstringFromStringWithTrim( ref processstr, ' ', 8 ) );
        f.Name = processstr;   //最后就是名稱
        return f;
    }

    /// <summary>
    /// 按照一定的規則進行字符串截取
    /// </summary>
    /// <param name="s">截取的字符串</param>
    /// <param name="c">查找的字符</param>
    /// <param name="startIndex">查找的位置</param>
    private string _cutSubstringFromStringWithTrim( ref string s, char c, int startIndex )
    {
        int pos1 = s.IndexOf( c, startIndex );
        string retString = s.Substring( 0, pos1 );
        s = ( s.Substring( pos1 ) ).Trim();
        return retString;
    }
    #endregion
    #region 目錄或文件存在的判斷
    /// <summary>
    /// 判斷當前目錄下指定的子目錄是否存在
    /// </summary>
    /// <param name="RemoteDirectoryName">指定的目錄名</param>
    public bool DirectoryExist( string RemoteDirectoryName )
    {
        try
        {
            if( !IsValidPathChars( RemoteDirectoryName ) )
            {
                throw new Exception( "目錄名非法!" );
            }
            FileStruct[] listDir = ListDirectories();
            foreach( FileStruct dir in listDir )
            {
                if( dir.Name == RemoteDirectoryName )
                {
                    return true;
                }
            }
            return false;
        }
        catch( Exception ep )
        {
            ErrorMsg = ep.ToString();
            throw ep;
        }
    }
    /// <summary>
    /// 判斷一個遠程文件是否存在服務器當前目錄下面
    /// </summary>
    /// <param name="RemoteFileName">遠程文件名</param>
    public bool FileExist( string RemoteFileName )
    {
        try
        {
            if( !IsValidFileChars( RemoteFileName ) )
            {
                throw new Exception( "文件名非法!" );
            }
            FileStruct[] listFile = ListFiles();
            foreach( FileStruct file in listFile )
            {
                if( file.Name == RemoteFileName )
                {
                    return true;
                }
            }
            return false;
        }
        catch( Exception ep )
        {
            ErrorMsg = ep.ToString();
            throw ep;
        }
    }
    #endregion
    #region 刪除文件
    /// <summary>
    /// 從FTP服務器上面刪除一個文件
    /// </summary>
    /// <param name="RemoteFileName">遠程文件名</param>
    public void DeleteFile( string RemoteFileName )
    {
        try
        {
            if( !IsValidFileChars( RemoteFileName ) )
            {
                throw new Exception( "文件名非法!" );
            }
            Response = Open( new Uri( this.Uri.ToString() + RemoteFileName ), WebRequestMethods.Ftp.DeleteFile );
        }
        catch( Exception ep )
        {
            ErrorMsg = ep.ToString();
            throw ep;
        }
    }
    #endregion
    #region 重命名文件
    /// <summary>
    /// 更改一個文件的名稱或一個目錄的名稱
    /// </summary>
    /// <param name="RemoteFileName">原始文件或目錄名稱</param>
    /// <param name="NewFileName">新的文件或目錄的名稱</param>
    public bool ReName( string RemoteFileName, string NewFileName )
    {
        try
        {
            if( !IsValidFileChars( RemoteFileName ) || !IsValidFileChars( NewFileName ) )
            {
                throw new Exception( "文件名非法!" );
            }
            if( RemoteFileName == NewFileName )
            {
                return true;
            }
            if( FileExist( RemoteFileName ) )
            {
                Request = OpenRequest( new Uri( this.Uri.ToString() + RemoteFileName ), WebRequestMethods.Ftp.Rename );
                Request.RenameTo = NewFileName;
                Response = ( FtpWebResponse ) Request.GetResponse();

            }
            else
            {
                throw new Exception( "文件在服務器上不存在!" );
            }
            return true;
        }
        catch( Exception ep )
        {
            ErrorMsg = ep.ToString();
            throw ep;
        }
    }
    #endregion
    #region 拷貝、移動文件
    /// <summary>
    /// 把當前目錄下面的一個文件拷貝到服務器上面另外的目錄中,注意,拷貝文件之后,當前工作目錄還是文件原來所在的目錄
    /// </summary>
    /// <param name="RemoteFile">當前目錄下的文件名</param>
    /// <param name="DirectoryName">新目錄名稱。
    /// 說明:如果新目錄是當前目錄的子目錄,則直接指定子目錄。如: SubDirectory1/SubDirectory2 ;
    /// 如果新目錄不是當前目錄的子目錄,則必須從根目錄一級一級的指定。如: ./NewDirectory/SubDirectory1/SubDirectory2
    /// </param>
    /// <returns></returns>
    public bool CopyFileToAnotherDirectory( string RemoteFile, string DirectoryName )
    {
        string CurrentWorkDir = this.DirectoryPath;
        try
        {
            byte[] bt = DownloadFile( RemoteFile );
            GotoDirectory( DirectoryName );
            bool Success = UploadFile( bt, RemoteFile, false );
            this.DirectoryPath = CurrentWorkDir;
            return Success;
        }
        catch( Exception ep )
        {
            this.DirectoryPath = CurrentWorkDir;
            ErrorMsg = ep.ToString();
            throw ep;
        }
    }
    /// <summary>
    /// 把當前目錄下面的一個文件移動到服務器上面另外的目錄中,注意,移動文件之后,當前工作目錄還是文件原來所在的目錄
    /// </summary>
    /// <param name="RemoteFile">當前目錄下的文件名</param>
    /// <param name="DirectoryName">新目錄名稱。
    /// 說明:如果新目錄是當前目錄的子目錄,則直接指定子目錄。如: SubDirectory1/SubDirectory2 ;
    /// 如果新目錄不是當前目錄的子目錄,則必須從根目錄一級一級的指定。如: ./NewDirectory/SubDirectory1/SubDirectory2
    /// </param>
    /// <returns></returns>
    public bool MoveFileToAnotherDirectory( string RemoteFile, string DirectoryName )
    {
        string CurrentWorkDir = this.DirectoryPath;
        try
        {
            if( DirectoryName == "" )
                return false;
            if( !DirectoryName.StartsWith( "/" ) )
                DirectoryName = "/" + DirectoryName;
            if( !DirectoryName.EndsWith( "/" ) )
                DirectoryName += "/";
            bool Success = ReName( RemoteFile, DirectoryName + RemoteFile );
            this.DirectoryPath = CurrentWorkDir;
            return Success;
        }
        catch( Exception ep )
        {
            this.DirectoryPath = CurrentWorkDir;
            ErrorMsg = ep.ToString();
            throw ep;
        }
    }
    #endregion
    #region 建立、刪除子目錄
    /// <summary>
    /// 在FTP服務器上當前工作目錄建立一個子目錄
    /// </summary>
    /// <param name="DirectoryName">子目錄名稱</param>
    public bool MakeDirectory( string DirectoryName )
    {
        try
        {
            if( !IsValidPathChars( DirectoryName ) )
            {
                throw new Exception( "目錄名非法!" );
            }
            if( DirectoryExist( DirectoryName ) )
            {
                throw new Exception( "服務器上面已經存在同名的文件名或目錄名!" );
            }
            string a = this.Uri.ToString();
            string b = DirectoryName;
            Response = Open( new Uri( this.Uri.ToString() + DirectoryName ), WebRequestMethods.Ftp.MakeDirectory );
            return true;
        }
        catch( Exception ep )
        {
            ErrorMsg = ep.ToString();
            throw ep;
        }
    }
    /// <summary>
    /// 從當前工作目錄中刪除一個子目錄
    /// </summary>
    /// <param name="DirectoryName">子目錄名稱</param>
    public bool RemoveDirectory( string DirectoryName )
    {
        try
        {
            if( !IsValidPathChars( DirectoryName ) )
            {
                throw new Exception( "目錄名非法!" );
            }
            if( !DirectoryExist( DirectoryName ) )
            {
                throw new Exception( "服務器上面不存在指定的文件名或目錄名!" );
            }
            Response = Open( new Uri( this.Uri.ToString() + DirectoryName ), WebRequestMethods.Ftp.RemoveDirectory );
            return true;
        }
        catch( Exception ep )
        {
            ErrorMsg = ep.ToString();
            throw ep;
        }
    }
    #endregion
    #region 文件、目錄名稱有效性判斷
    /// <summary>
    /// 判斷目錄名中字符是否合法
    /// </summary>
    /// <param name="DirectoryName">目錄名稱</param>
    public bool IsValidPathChars( string DirectoryName )
    {
        char[] invalidPathChars = Path.GetInvalidPathChars();
        char[] DirChar = DirectoryName.ToCharArray();
        foreach( char C in DirChar )
        {
            if( Array.BinarySearch( invalidPathChars, C ) >= 0 )
            {
                return false;
            }
        }
        return true;
    }
    /// <summary>
    /// 判斷文件名中字符是否合法
    /// </summary>
    /// <param name="FileName">文件名稱</param>
    public bool IsValidFileChars( string FileName )
    {
        char[] invalidFileChars = Path.GetInvalidFileNameChars();
        char[] NameChar = FileName.ToCharArray();
        foreach( char C in NameChar )
        {
            if( Array.BinarySearch( invalidFileChars, C ) >= 0 )
            {
                return false;
            }
        }
        return true;
    }
    #endregion
    #region 目錄切換操作
    /// <summary>
    /// 進入一個目錄
    /// </summary>
    /// <param name="DirectoryName">
    /// 新目錄的名字。
    /// 說明:如果新目錄是當前目錄的子目錄,則直接指定子目錄。如: SubDirectory1/SubDirectory2 ;
    /// 如果新目錄不是當前目錄的子目錄,則必須從根目錄一級一級的指定。如: ./NewDirectory/SubDirectory1/SubDirectory2
    /// </param>
    public bool GotoDirectory( string DirectoryName )
    {
        string CurrentWorkPath = this.DirectoryPath;
        try
        {
            DirectoryName = DirectoryName.Replace( "/", "/" );
            string[] DirectoryNames = DirectoryName.Split( new char[] { '/' } );
            if( DirectoryNames[ 0 ] == "." )
            {
                this.DirectoryPath = "/";
                if( DirectoryNames.Length == 1 )
                {
                    return true;
                }
                Array.Clear( DirectoryNames, 0, 1 );
            }
            bool Success = false;
            foreach( string dir in DirectoryNames )
            {
                if( dir != null )
                {
                    Success = EnterOneSubDirectory( dir );
                    if( !Success )
                    {
                        this.DirectoryPath = CurrentWorkPath;
                        return false;
                    }
                }
            }
            return Success;

        }
        catch( Exception ep )
        {
            this.DirectoryPath = CurrentWorkPath;
            ErrorMsg = ep.ToString();
            throw ep;
        }
    }
    /// <summary>
    /// 從當前工作目錄進入一個子目錄
    /// </summary>
    /// <param name="DirectoryName">子目錄名稱</param>
    private bool EnterOneSubDirectory( string DirectoryName )
    {
        try
        {
            if( DirectoryName.IndexOf( "/" ) >= 0 || !IsValidPathChars( DirectoryName ) )
            {
                throw new Exception( "目錄名非法!" );
            }
            if( DirectoryName.Length > 0 && DirectoryExist( DirectoryName ) )
            {
                if( !DirectoryName.EndsWith( "/" ) )
                {
                    DirectoryName += "/";
                }
                _DirectoryPath += DirectoryName;
                return true;
            }
            else
            {
                return false;
            }
        }
        catch( Exception ep )
        {
            ErrorMsg = ep.ToString();
            throw ep;
        }
    }
    /// <summary>
    /// 從當前工作目錄往上一級目錄
    /// </summary>
    public bool ComeoutDirectory()
    {
        if( _DirectoryPath == "/" )
        {
            ErrorMsg = "當前目錄已經是根目錄!";
            throw new Exception( "當前目錄已經是根目錄!" );
        }
        char[] sp = new char[ 1 ] { '/' };

        string[] strDir = _DirectoryPath.Split( sp, StringSplitOptions.RemoveEmptyEntries );
        if( strDir.Length == 1 )
        {
            _DirectoryPath = "/";
        }
        else
        {
            _DirectoryPath = String.Join( "/", strDir, 0, strDir.Length - 1 );
        }
        return true;

    }
    #endregion
    #region 重載WebClient,支持FTP進度
    internal class MyWebClient : WebClient
    {
        protected override WebRequest GetWebRequest( Uri address )
        {
            FtpWebRequest req = ( FtpWebRequest ) base.GetWebRequest( address );
            req.UsePassive = false;
            return req;
        }
    }
    #endregion
}

}</pre>

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!