經過幾天的練習(沉潛....), 我又收到一個不太簡單的工作,是將本地端的檔案,上傳到遠端的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 進行檔案上傳的說明, 希望對大家有幫助
留言
張貼留言