跳到主要內容

dotnet core 3.1 進行FTP 檔案上傳作業

 經過幾天的練習(沉潛....), 我又收到一個不太簡單的工作,是將本地端的檔案,上傳到遠端的FTP資料夾,且必須依據資料時間進行資料夾的設定.....

剛看到這個需求,外面剛好打了一陣雷,下起今年缺很久的春雨...

單純FTP上傳功能還不算有太大難度,只要遠端FTP資料夾權限有開啟,即可進行檔案上傳的動作,但是如果需要在遠端的FTP上面再建立一層資料夾,這裡會多一道工作,就是確認資料夾的路徑、在FTP連線上面建立新的資料夾....等等



首先要上傳資料以前,必須先建立相對應的資料夾路徑,假設我要將檔案上傳到 

ftp://hello.com.tw/20210505/Hello.txt ,其中 「hello.com.tw」 網址是屬於 FTP 的root位置, 而「20210505」則是我們要在FTP建立的資料夾名稱,要透過Ftp的工具物件進行檔案上傳以前,必須先建立這個資料夾


原本之前我是比較習慣用VS 進行開發,畢竟大部份的專案都還是以dotnet framework 的底層為主。

但是如果要進行這項功能的測試,考量 WebRequest 的類別在dotnet core 的環境也是放在System.Net,且不想另外再建立一個 dotnet framework專案, 於是就用最近剛剛上手的 dotnet core 3.1 進行功能測試撰寫


這裡一樣是用console 專案進行測試,其中與FTP有關的連線參數,我會用 .json 作為組態檔案進行定義,然後將相關的參數在 Main Method 進入點做賦值

        static void Main(string[] args)
        {                     
            //這裡會用ReadFromMySettings()取得json 的內容
            var ftp_infos = ReadFromMySettings().GetSection("FtpSetting").GetSection("Saho1");
            account = ftp_infos.GetSection("FtpAccount").Value;  //取得FTP帳號
            pwd = ftp_infos.GetSection("FtpPass").Value;   //取得密碼
            server_name = ftp_infos.GetSection("FtpServer").Value;  //取得FTP站台名稱
            port = ftp_infos.GetSection("PortNumber").Value;    //取得Port Number
            path_name = ftp_infos.GetSection("Uploadpath").Value;
            for(int i=5;i>=0;i--){
                Console.WriteLine(StringWithInt.GetStringWithIntStr(i));
                Console.WriteLine(StringWithInt.GetStringWithIntStr(-i));
            }
            try{
                Upload(ftp_infos.GetSection("FileName").Value); //將參數裡指定的檔案進行上傳
            }
            catch(WebException ex)
            {
                WebResponse errResp = ex.Response;
                using (Stream respStream = errResp.GetResponseStream())
                {
                    StreamReader reader = new StreamReader(respStream);
                    string text = reader.ReadToEnd();
                    Console.WriteLine(text);
                }
            
            }
            catch(Exception ex){
                Console.WriteLine(ex.Message);
            }
            
            Console.Read();
        }

    

        這是用來取得 settings.json 組態檔參數的 ReadFromMySettings() 方法,它會回傳一個實作IConfigurationRoot 的類別,然後再取得configuration 的相關區段參數,希望有時間我再另開一篇文章說明



接下來進入到本章的重點,檔案上傳設定, Upload的主要功能是將本地端檔案傳送到遠端的FTP 方法
,其中這裡是指定傳送到遠端FTP的 EquNo2 資料夾, 某些情況之下這個資料夾可能是尚未建立的,因此我會再透過 SetCreateFold(string FoldName) 在FTP上面再建立資料夾

public static void Upload(string FileName){
            SetCreateFold("EquNo2");    //建立遠端的資料夾
            FileInfo fileInf = new FileInfo(FileName);            
            string uri = "ftp://"+server_name +"/EquNo2/"+fileInf.Name;
            // Get the object used to communicate with the server.
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(uri);
            request.Method = WebRequestMethods.Ftp.UploadFile;
            request.Credentials = new NetworkCredential(account, pwd);
            // Copy the contents of the file to the request stream.
            byte[] fileContents;
            fileContents = File.ReadAllBytes(FileName);
            request.ContentLength = fileContents.Length;
            using (Stream requestStream = request.GetRequestStream())
            {
                requestStream.Write(fileContents, 0, fileContents.Length);
            }

            using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
            {
                Console.WriteLine($"Upload File Complete, status {response.StatusDescription}");
            }
        }


這個部份是用來建立FTP上面的資料夾(這裡假設FoldName尚未存在於遠端的FTP),
網址由原本的ftp root 再加上資料夾名稱        
        public static void SetCreateFold(string FoldName){
            string uri = "ftp://"+server_name + "/" +FoldName;
            // Get the object used to communicate with the server.
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(uri);
            request.Method = WebRequestMethods.Ftp.MakeDirectory;            
            request.Credentials = new NetworkCredential(account,pwd);   //這裡做ftp的使用者認證
            using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
            using(Stream respStream=response.GetResponseStream())
            {
                StreamReader reader = new StreamReader(respStream);
                string text = reader.ReadToEnd();
                Console.WriteLine("完成建立資料夾");
                Console.WriteLine(text);
            }
        }

因為是要建立遠端的資料夾,所以FTP的執行命令須進行修改, FtpWebRequest.Method 要設定為
WebRequestMethods.Ftp.MakeDirectory, 這邊是跟Upload 的差異

另外在建立遠端FTP的資料夾,還要注意資料夾不得重複建立,否則會出現Exception 的情況,若要避免這種情形, 則在資料夾建立以前,先進行資料夾的驗證,這裡可以另外再做一個方法,其中的差異就是
FtpWebRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails ;

將命令 Method 改為 「WebRequestMethods.Ftp.ListDirectoryDetails

FtpWebRequest.Method 可以參考以下這篇說明


完成 SetCreateFold 方法 建立遠端資料夾以後,再繼續進行FTP檔案上傳的後續指令,上面連結也有提到 檔案上傳的部份,主要是要透過 GetRequestStream() 加載本地端的檔案資訊,且須將執行指令設為 「WebRequestMethods.Ftp.UploadFile

以上就是透過 FtpWebRequest 進行檔案上傳的說明, 希望對大家有幫助



留言