跳到主要內容

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 進行檔案上傳的說明, 希望對大家有幫助



留言

這個網誌中的熱門文章

右昌的古厝、老街坊

大社老街屋巡禮

  這座三合院的馬背雕飾蠻細工的 上面兩幢的側牆馬背,都有特別的雕飾,這是常見的三合院風格 在我走回程往我家的方向,又看到幾座大院,後頭都是現代化的樓房 這座三合院蠻有規模的,院子邊還有一座古井,也很有歷史了 這是舊三合院的側屋殘壁,屋頂損壞後就沒再修護了 三合院的側牆 走到了三奶里,這邊就有三座古厝 大社最有名的巫家老厝,老厝是在大社的市中心,黃昏市場外面 老厝的院子保存的很完整 大院的右側一角 老厝的左側小旁門 巫家老厝外院 這座古厝在大社三奶里也蠻有名的 大瓦厝的側邊外牆 房子外牆很典雅,搭配裡面有層次的老建物 房子後頭的一塊小田地,有點像我以前屏東阿嬤家的古厝風格 這個景色很像油畫上面看到的,這區塊的古厝週邊都蓋滿了樓房 走到了大社觀音里後可以看到密集的巷弄老房 巷底的老房子,窗戶上緣有雕花裝飾 老三合院的正廳 巷弄邊老房子一角 在街上看到老房子常常有這個廣告 老巷弄與老房,搭配著新跑車 觀音里的老巷弄三合院

好久沒在家附近散步,順便拍些附近的街景

位在大社中華路的黃家古厝,這是大社的古蹟之一 這是觀音里的設區協會 有彩繪的外牆 老街巷弄的老屋 在大社的舊巷弄還是可以看到這些老屋 巷弄裡的三合院建築群 這座三合院主體保留的很完整 在院子一角,發現這座古董,這個是石磨,以前農村裡面常常可以看到 中華路旁邊有一處小公園 這是在中華路上一處蠻顯眼的三合大院 除了三合院,也有許多傳統的二層樓房 這座三合院外牆還有一面屏風