目錄
什么是FTP服務器
搭建FTP服務器相關
?編輯
Unity中與FTP相關的類
上傳文件到FTP服務器
使用FTP服務器上傳文件的關鍵點
開始上傳
從FTP服務器下載文件到客戶端
使用FTP下載文件的關鍵點
開始下載
關于FTP服務器的其他操作
將文件的上傳,下載,刪除等其他操作使用面向對象的思想用單例模式進行封裝
測試FTPMgr模塊的功能
什么是FTP服務器
- 基本概念:FTP 是文件傳輸協議(File Transfer Protocol)的縮寫,FTP 服務器就是遵循該協議,專門用來存儲和管理文件,并為用戶提供文件上傳和下載服務的服務器。用戶可以通過 FTP 客戶端軟件連接到 FTP 服務器,進行文件的傳輸操作。
- 功能特點
- 文件傳輸:支持文件的上傳和下載,用戶可以將本地計算機上的文件上傳到 FTP 服務器,也可以從 FTP 服務器下載所需的文件到本地。
- 用戶管理:可以設置不同的用戶賬戶,并為每個用戶分配不同的權限,如讀取、寫入、刪除等權限,從而實現對文件訪問的精細控制。
- 目錄管理:允許創建、刪除、重命名目錄,以及在目錄之間移動文件等操作,方便對文件進行組織和管理。
搭建FTP服務器相關
#region 知識點一 搭建FTP服務器的幾種方式//1.使用別人做好的FTP服務器軟件 (學習階段建議使用)//2.自己編寫FTP服務器應用程序,基于FTP的工作原理,用Socket中TCP通信來進行編程(工作后由后端程序員來做) //3.將電腦搭建為FTP文件共享服務器 (工作后由后端程序員來做)//第2,3點我們前端程序主要做了解 //一般在工作中不會由我們來完成這部分工作#endregion #region 知識點二 使用別人做好的FTP服務器軟件來搭建FTP服務器//下載Serv-U等FTP服務器軟件 //在想要作為FTP服務器的電腦上運行之 //1.創建域 直接不停下一步即可 //2.使用單向加密 //3.創建用于上傳下載的FTP 賬號和密碼#endregion #region 總結 //在實際商業項目開發當中,如果需要用FTP來進行文件傳輸 //那么FTP服務器的解決方案都是由后端程序員來完成的 //不管它使用哪種方式來搭建FTP服務器 //只要能正常上傳下載內容并且保證安全性即可#endregion
我們使用Serv-U服務器作為我們的FTP服務器
Unity中與FTP相關的類
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using UnityEngine;public class Lesson18 : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){#region 知識點一 NetWorkCredential類//命名空間:System.Net//NetWorkCredential通信憑證類//用于在FTP文件傳輸時,設置賬號密碼NetworkCredential n = new NetworkCredential("DamnF", "DamnF123");#endregion#region 知識點二 FtpWebRequest類//命名空間:System.Net//Ftp文件傳輸協議客戶端操作類//主要用于:上傳,下載,刪除服務器上的文件//重要方法//1.Create 創建新的WebRequest,用于進行相關的Ftp相關操作FtpWebRequest req =FtpWebRequest.Create(new Uri("ftp://127.0.0.1/Test.txt"))as FtpWebRequest;//2.Abort 如果正在進行文件傳輸,用此方法可以終止文件傳輸req.Abort();//3.GetRequestStream 獲取用于上傳的流Stream s= req.GetRequestStream();//4.GetResponse 返回Ftp服務器響應//FtpWebResponse res= req.GetResponse()as FtpWebResponse;//重要成員//1.Credentials 通信憑證,設置為NetWorkCredential對象req.Credentials = n;//2.KeepAlive bool值,當完成請求時是否關閉到Ftp服務器的控制連接(默認為true,不關閉);req.KeepAlive = false;//3.Method 操作命令設置// WebRequestMethods.Ftp類中的操作命令屬性// DeleteFile 刪除文件// DownloadFile 下載文件// ListDirectory 獲取文件簡短列表// ListDirectoryDetails 獲取文件詳細列表// MakeDirectory 創建目錄// RemoveDirectory 刪除目錄// UploadFile 上傳文件req.Method = WebRequestMethods.Ftp.DownloadFile;//4.UseBinary 是否使用2進制傳輸req.UseBinary = true;//5.RenameTo 重命名req.RenameTo = "myTest.txt";#endregion#region 知識點三 FtpWebResponse類//命名空間:System.Net//它是用于封裝Ftp服務器對請求的響應//它提供操作狀態和從服務器下載數據//我們可以通過FtpWebRequest對象中的GetResponse()方法獲取//當使用完畢時,要使用Close釋放//通過它真正獲取服務器的內容FtpWebResponse res = req.GetResponse() as FtpWebResponse;//重要方法//1.Close:釋放所有資源res.Close();//2.GetResponseStream:返回從Ftp下載數據的流Stream stream= res.GetResponseStream();//重要成員//1.ContentLength:接收到數據的長度print(res.ContentLength);//2.ContentType:接收到數據的類型print(res.ContentType);//3.StatusCode:Ftp服務器下發的最新狀態碼print(res.StatusCode);//4.StatusDescription:Ftp服務器下發的狀態代碼的文本print(res.StatusDescription);//5.BannerMessage:登錄前建立連接時Ftp服務器下發的消息print(res.BannerMessage);//6.ExitMessage:Ftp會話結束時服務器發送的消息print(res.ExitMessage);//7.LastModified:Ftp服務器上的文件的上次修改日期和時間print(res.LastModified);#endregion#region 總結//通過C#提供的3個類//我們就可以完成客戶端向Ftp服務器//操作文件的需求,比如//上傳,下載,刪除文件#endregion }// Update is called once per framevoid Update(){}
}
上傳文件到FTP服務器
使用FTP服務器上傳文件的關鍵點
? ? ? ? //1.通信憑證
? ? ? ? // ?進行FTP連接時操作時的賬號和密碼
? ? ? ? //2.操作命令WebRequestMethod.Ftp
? ? ? ? // 設置你想要進行的Ftp操作
? ? ? ? //3.文件流相關FileStream和Stream
? ? ? ? // ?上傳和下載時都會使用到文件流
? ? ? ? //4.保證ftp服務器已經開啟
? ? ? ? // 并且能夠正確訪問
開始上傳
try{//1.創建一個Ftp連接FtpWebRequest req = FtpWebRequest.Create(new Uri("ftp://127.0.0.1/pic.png")) as FtpWebRequest;//2.設置通信憑證(如果不支持匿名,就必須設置這一步)//將代理相關設置置空 避免服務器同時有http相關服務沖突req.Proxy = null;NetworkCredential n = new NetworkCredential("DamnF", "DamnF123");req.Credentials = n;//請求完畢后,是否關閉控制連接,如果想要關閉,需要設置falsereq.KeepAlive = false;//3.設置操作命令req.Method = WebRequestMethods.Ftp.UploadFile;//設置操作命令為上傳文件//4.指定傳輸類型req.UseBinary = true;//5.得到用于上傳的流對象Stream upLoadStream = req.GetRequestStream();//6.開始上傳using (FileStream file = File.OpenRead(Application.streamingAssetsPath + "/test.png")){//我們可以一點一點的把這個文件中的字節數組讀取出來 然后存到上傳流中byte[] bytes = new byte[1024];//返回值是真正從文件中讀了多少個字節int contentLength = file.Read(bytes, 0, bytes.Length);//不停的去讀取文件中的字節流 除非讀完了 不然一直讀 并且寫入到上傳流中while (contentLength != 0){//寫入上傳流中upLoadStream.Write(bytes, 0, contentLength);//寫完了繼續讀取contentLength = file.Read(bytes, 0, bytes.Length);}//出了循環就證明寫完了file.Close();upLoadStream.Close();//上傳完畢print("上傳完畢");}}catch (Exception e){print("上傳失敗 出錯了" + e.Message);}
從FTP服務器下載文件到客戶端
使用FTP下載文件的關鍵點
? ? ? ? //1.通信憑證
? ? ? ? // 進行FTP文件操作時需要的賬號和密碼
? ? ? ? //2.操作命令WebRequestMethods.Ftp
? ? ? ? // 設置你想要進行的Ftp操作
? ? ? ? //3.文件流相關的FileStream和Stream
? ? ? ? // 上傳和下載時都需要使用的文件流
? ? ? ? // 下載文件流使用FtpWebResponse類獲取
? ? ? ? //4.保證Ftp服務器已開啟
? ? ? ? // 并且能夠正常訪問
開始下載
try{//1.創建一個Ftp連接//這里和上傳不同,上傳的文件名是自己定的 下載的文件名必須是資源服務器里有的FtpWebRequest req = FtpWebRequest.Create(new Uri("ftp://127.0.0.1/文本格式.jpg")) as FtpWebRequest;//2.設置一個通信憑證(如果不支持匿名,就必須設置這一步)//請求完畢后 是否關閉控制連接,如果要進行多次操作 可以設置falseNetworkCredential n = new NetworkCredential("DamnF", "DamnF123");req.Credentials = n;req.KeepAlive = false;//3.設置操作命令req.Method = WebRequestMethods.Ftp.DownloadFile;//4.指定傳輸類型req.UseBinary = true;req.Proxy = null;//5.得到用于上傳的流對象//相當于把請求發送給ftp服務器,就會攜帶我們想要的信息返回FtpWebResponse res = req.GetResponse()as FtpWebResponse;//這就是下載流Stream DownLoadStream = res.GetResponseStream ();//6.開始上傳print(Application.persistentDataPath);using (FileStream file = File.Create(Application.persistentDataPath + "/DamnF112233.jpg")){byte[] bytes = new byte[1024];int contentLength = file.Read(bytes, 0, bytes.Length);while (contentLength != 0){file.Write(bytes, 0, contentLength);contentLength = file.Read(bytes, 0, bytes.Length);}file.Close();DownLoadStream.Close();print("下載完畢");}}catch (Exception e){print("下載出錯了" + e.Message);}
關于FTP服務器的其他操作
?//除了上傳和下載,還有其他操作
? ? ? ? //比如:
? ? ? ? //1.刪除文件
? ? ? ? //2.獲取文件大小
? ? ? ? //3.創建文件夾
? ? ? ? //4.獲取文件列表
? ? ? ? //等等
將文件的上傳,下載,刪除等其他操作使用面向對象的思想用單例模式進行封裝
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Events;public class FtpMgr
{private static FtpMgr instance=new FtpMgr();public static FtpMgr Instance => instance;//ftp服務器地址private string FTP_PATH = "ftp://127.0.0.1";//用戶名密碼private string USER_NAME = "DamnF";private string PASSWORD = "DamnF123";public async void UpLoadFile(string fileName,string localPath,UnityAction action=null){await Task.Run(() =>{try{//通過一個線程執行這里邊的邏輯,不會影響主線程//1.創建ftp連接FtpWebRequest req = FtpWebRequest.Create(new Uri(FTP_PATH+fileName)) as FtpWebRequest;//2.設置通信憑證(如果不支持匿名,就必須設置這一步)//將代理相關設置置空 避免服務器同時有http相關服務沖突req.Proxy = null;NetworkCredential n = new NetworkCredential(USER_NAME, PASSWORD);req.Credentials = n;//請求完畢后,是否關閉控制連接,如果想要關閉,需要設置falsereq.KeepAlive = false;//3.設置操作命令req.Method = WebRequestMethods.Ftp.UploadFile;//4.指定傳輸類型req.UseBinary = true;//5.得到用于上傳的流對象Stream upLoadStream = req.GetRequestStream();//6.開始上傳using (FileStream file = File.OpenRead(localPath)){//我們可以一點一點的把這個文件中的字節數組讀取出來 然后存到上傳流中byte[] bytes = new byte[1024];//返回值是真正從文件中讀了多少個字節int contentLength = file.Read(bytes, 0, bytes.Length);//不停的去讀取文件中的字節流 除非讀完了 不然一直讀 并且寫入到上傳流中while (contentLength != 0){//寫入上傳流中upLoadStream.Write(bytes, 0, contentLength);//寫完了繼續讀取contentLength = file.Read(bytes, 0, bytes.Length);}//出了循環就證明寫完了file.Close();upLoadStream.Close();}//上傳完畢Debug.Log("上傳完畢");}catch (Exception e){Debug.Log("上傳出錯了" + e.Message);}});//上傳結束后,你想在外部做的事情action?.Invoke();}public async void DownLoadFile(string fileName,string localName,UnityAction action=null){await Task.Run(() =>{try{FtpWebRequest req = FtpWebRequest.Create(new Uri(FTP_PATH + fileName)) as FtpWebRequest;NetworkCredential n = new NetworkCredential(USER_NAME, PASSWORD);req.Credentials = n;req.KeepAlive = false;req.Proxy = null;req.UseBinary = true;req.Method = WebRequestMethods.Ftp.DownloadFile;FtpWebResponse res = req.GetResponse() as FtpWebResponse;Stream DownLoadStream = res.GetResponseStream();using (FileStream file = File.Create(localName)){byte[] bytes = new byte[1024];int contentLength = file.Read(bytes, 0, bytes.Length);while (contentLength != 0){file.Write(bytes, 0, contentLength);contentLength = file.Read(bytes, 0, bytes.Length);}file.Close();DownLoadStream.Close();Debug.Log("下載完畢");}res.Close();}catch (Exception e){Debug.Log("下載出錯了" + e.Message);}});action?.Invoke();}public async void DeleteFile(string fileName,UnityAction<bool> action=null){await Task.Run(() =>{try{FtpWebRequest req = FtpWebRequest.Create(new Uri(FTP_PATH + fileName)) as FtpWebRequest;NetworkCredential n = new NetworkCredential(USER_NAME, PASSWORD);req.Credentials = n;req.Proxy = null;req.KeepAlive = false;req.UseBinary = true;req.Method = WebRequestMethods.Ftp.DeleteFile;FtpWebResponse res = req.GetResponse() as FtpWebResponse;res.Close();action?.Invoke(true);}catch (Exception e){Debug.Log("刪除文件出錯"+e.Message);action?.Invoke(false);}});}public async void GetFileSize(string fileName,UnityAction<long>action=null){try{await Task.Run(() =>{FtpWebRequest req = FtpWebRequest.Create(new Uri(FTP_PATH + fileName)) as FtpWebRequest;NetworkCredential n = new NetworkCredential(USER_NAME, PASSWORD);req.Credentials = n;req.KeepAlive = false;req.Proxy = null;req.UseBinary = true;req.Method = WebRequestMethods.Ftp.GetFileSize;FtpWebResponse res = req.GetResponse() as FtpWebResponse;action?.Invoke(res.ContentLength);res.Close();});}catch (Exception e){Debug.Log("得到文件大小出錯" + e.Message);}}public async void CreateDirectory(string DirectoryName,UnityAction<bool>action=null){try{await Task.Run(() =>{FtpWebRequest req = FtpWebRequest.Create(new Uri(FTP_PATH + DirectoryName)) as FtpWebRequest;NetworkCredential n = new NetworkCredential(USER_NAME, PASSWORD);req.Credentials = n;req.Proxy = null;req.KeepAlive = false;req.UseBinary = true;req.Method = WebRequestMethods.Ftp.MakeDirectory;FtpWebResponse res = req.GetResponse() as FtpWebResponse;res.Close();action?.Invoke(true);});}catch (Exception e){Debug.Log("文件夾創建失敗" + e.Message);action?.Invoke(false);}}public async void GetFileList(string directoryName,UnityAction<List <string>>action=null){try{await Task.Run(() =>{FtpWebRequest req = FtpWebRequest.Create(new Uri(FTP_PATH + directoryName)) as FtpWebRequest;NetworkCredential n = new NetworkCredential(USER_NAME, PASSWORD);req.Credentials = n;req.Proxy = null;req.KeepAlive = false;req.UseBinary = true;req.Method = WebRequestMethods.Ftp.ListDirectory;FtpWebResponse res = req.GetResponse() as FtpWebResponse;//把下載的信息流轉化為StreamReader對象,方便我們一行一行的讀取信息StreamReader streamReader = new StreamReader(res.GetResponseStream());//用于存儲文件名的列表List<string> nameStrs = new List<string>();//一行一行的讀取信息string line= streamReader.ReadLine();while(line!=null){nameStrs.Add(line);line = streamReader.ReadLine();}action?.Invoke(nameStrs);res.Close();});}catch (Exception e){Debug.Log("文件列表返回失敗" + e.Message);action?.Invoke(null);}}
}
測試FTPMgr模塊的功能
FtpMgr.Instance.UpLoadFile("/DamnFPic.png", Application.streamingAssetsPath + "/test.png", () =>{print("上傳成功,調用委托函數");});print("測試測試");print(Application.persistentDataPath);FtpMgr.Instance.DownLoadFile("/文本格式.jpg", Application .persistentDataPath +"/zhangdeshuai1234.jpg", () => {print("下載成功,調用委托函數");});print("測試測試");
//1.刪除文件FtpMgr.Instance.DeleteFile("/Pic.png", (result) =>{print(result ? "刪除完畢" : "刪除失敗");});//2.獲取文件大小FtpMgr.Instance.GetFileSize("/文本格式.jpg", (result) => {print("文件大小是:" + result);});//3.創建文件夾FtpMgr.Instance.CreateDirectory("/DamnF", (result) => {print(result ? "創建成功" : "創建失敗");});//4.獲取文件列表FtpMgr.Instance.GetFileList("", (list) => {if(list==null){print("返回文件列表失敗");return;}else{for (int i = 0; i < list.Count ; i++){print(list[i]);}}});