FTP的工作原理
-
FTP 文件传输协议的本质是 TCP 通信
-
FTP 有两种传输模式
主动模式 (Port 模式) 和 被动模式 (Passive 模式)
-
FTP 有两种传输方式
ASCII 传输 和 二进制传输(建议使用)
-
FTP 传输文件时需要用户名和密码登录
如果服务器允许,也可以匿名登录
FTP相关重要类讲解
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using UnityEngine;
public class lesson9 : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
/*
* NetworkCredential类
* 命名空间:System.Net
* NetworkCredential通信凭证类
* 用于在Ftp文件传输时,设置账号密码
*/
NetworkCredential n = new NetworkCredential("xxxxxx","xxxxxx");
//FtpWebRequest 类
// 命名空间: System.Net
//Ftp 文件传输协议客户端操作类
// 主要用于:上传、下载、删除服务器上的文件
// 重要方法
//1.Create 创建新的 WebRequest,用于进行 Ftp 相关操作
FtpWebRequest req = FtpWebRequest.Create(new Uri("ftp://127.0.0.1")) as FtpWebRequest;
//2.Abort 如果正在进行文件传输,用此方法可以终止传输
req.Abort();
//3.GetRequestStream 获取用于上传的流
Stream stream = req.GetRequestStream();
//4.GetResponse 返回 FTP 服务器响应
//FtpWebResponse response = 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 = "xxxx.txt";
// FtpWebResponse 类
// 命名空间: System.Net
// 它是用于封装 FTP 服务器对请求的响应
// 它提供操作状态以及从服务器下载数据
// 我们可以通过 FtpWebRequest 对象中的 GetResponse () 方法获取
// 当使用完毕时,要使用 Close 释放
FtpWebResponse response = req.GetResponse() as FtpWebResponse;
// 重要方法:
//1.Close: 释放所有资源
response.Close();
//2.GetResponseStream: 返回从 FTP 服务器下载数据的流
Stream stream1 = response.GetResponseStream();
// 重要成员:
//1.ContentLength: 接受到数据的长度
print(response.ContentLength);
//2.ContentType: 接受数据的类型
//3.StatusCode:FTP 服务器下发的最新状态码
//4.StatusDescription:FTP 服务器下发的状态代码的文本
//5.BannerMessage: 登录前建立连接时 FTP 服务器发送的消息
//6.ExitMessage:FTP 会话结束时服务器发送的消息
//7.LastModified:FTP 服务器上的文件的上次修改日期和时间
}
// Update is called once per frame
void Update()
{
}
}
FTP文件上传
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using UnityEngine;
public class lesson9_1 : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
try
{
//FTP上传
//创建一个FTP连接
FtpWebRequest req = FtpWebRequest.Create(new Uri("ftp://127.0.0.1/pic.png")) as FtpWebRequest;
//设置通信凭证(如果不支持匿名 就必须设置这一步)
//将代理相关信息设置为空 避免服务器同时有http相关服务造成冲突
req.Proxy = null;
NetworkCredential network = new NetworkCredential("账号", "密码");
req.Credentials = network;
//请求完毕后 是否关闭控制连接,如果想要关闭可以设置为false
req.KeepAlive = false;
//3.设置操作命令
req.Method = WebRequestMethods.Ftp.UploadFile;
//4.指定传输类型
req.UseBinary = true;
//5.得到用于上传的流对象
Stream stream = req.GetRequestStream();
//6.开始上传
using (FileStream fs = File.Open(Application.streamingAssetsPath + "/test.png", FileMode.Open, FileAccess.Read))
{
print(Application.streamingAssetsPath);
byte[] bytes = new byte[1024];
int contentLength = fs.Read(bytes, 0, bytes.Length);
while (contentLength != 0)
{
stream.Write(bytes, 0, contentLength);
contentLength = fs.Read(bytes, 0, bytes.Length);
}
fs.Close();
stream.Close();
print("上传完成");
}
}
catch (Exception ex)
{
print("上传失败");
}
}
// Update is called once per frame
void Update()
{
}
}
使用单例模式,封装方法完成文件上传
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 = "XXXXXX";
private string PASSWORD = "XXXXXX";
public async void UpLoadFile(string fileName, string localPath,UnityAction action = null)
{
await Task.Run(() =>
{
//通过一个线程执行这里面的逻辑,就不会影响主线程
try
{
FtpWebRequest req = FtpWebRequest.Create(new Uri(FTP_PATH+"/"+fileName)) as FtpWebRequest;
req.Proxy = null;
NetworkCredential network = new NetworkCredential(USER_NAME, PASSWORD);
req.Credentials = network;
req.KeepAlive = false;
req.Method = WebRequestMethods.Ftp.UploadFile;
req.UseBinary = true;
Stream stream = req.GetRequestStream();
using (FileStream fs = File.OpenRead(localPath))
{
byte[] buffer = new byte[1024];
int temp = fs.Read(buffer, 0, buffer.Length);
while (temp != 0)
{
stream.Write(buffer, 0, temp);
temp = fs.Read(buffer, 0,buffer.Length);
}
Debug.Log("上传成功");
fs.Close();
stream.Close();
}
}
catch (Exception ex)
{
Debug.Log("上传失败"+ ex.Message);
}
});
//上传结束后希望执行的函数
action?.Invoke();
}
}
测试脚本
FtpMgr.Instance.UpLoadFile("test2.png", Application.streamingAssetsPath + "/test.png", () => {
print("上传完成执行函数");
});

FTP文件下载
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using UnityEngine;
public class lesson9_2 : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
try
{
//FTP下载
//创建一个FTP连接
FtpWebRequest request = FtpWebRequest.Create(new Uri("ftp://127.0.0.1/test2.png")) as FtpWebRequest;
//设置通信凭证
request.Proxy = null;
NetworkCredential credential = new NetworkCredential("XXXXXX", "XXXXXX");
request.Credentials = credential;
//请求完毕后是否关闭控制连接
request.KeepAlive = false;
//设置操作命令
request.Method = WebRequestMethods.Ftp.DownloadFile;
//指定传输类型
request.UseBinary = true;
//得到用于下载的流对象
FtpWebResponse response = request.GetResponse() as FtpWebResponse;
Stream stream = response.GetResponseStream();
//开始下载
using (FileStream fs = File.Open(Application.persistentDataPath + "/123.png", FileMode.OpenOrCreate, FileAccess.Write))
{
print(Application.persistentDataPath);
byte[] buffer = new byte[1024];
int length = stream.Read(buffer, 0, buffer.Length);
while (length != 0)
{
fs.Write(buffer, 0, length);
length = stream.Read(buffer, 0, buffer.Length);
}
print("下载完成");
fs.Close();
stream.Close();
}
}
catch (Exception e)
{
print("下载失败");
Debug.Log(e);
}
}
// Update is called once per frame
void Update()
{
}
}
单例模式添加下载函数
public async void DownLoadFile(string fileName, string localPath, UnityAction action = null)
{
await Task.Run(() =>
{
try
{
FtpWebRequest req = FtpWebRequest.Create(new Uri(FTP_PATH + "/" + fileName)) as FtpWebRequest;
req.Proxy = null;
NetworkCredential network = new NetworkCredential(USER_NAME, PASSWORD);
req.Credentials = network;
req.KeepAlive = false;
req.Method = WebRequestMethods.Ftp.DownloadFile;
req.UseBinary = true;
FtpWebResponse response = req.GetResponse() as FtpWebResponse;
Stream stream = response.GetResponseStream();
using (FileStream fs = File.Create(localPath))
{
byte[] buffer = new byte[1024];
int length = stream.Read(buffer, 0, buffer.Length);
while (length != 0)
{
fs.Write(buffer, 0, length);
length = stream.Read(buffer, 0, buffer.Length);
}
Debug.Log("下载成功");
fs.Close();
stream.Close();
}
}
catch (Exception ex)
{
Debug.Log("下载失败:"+ex.Message);
}
});
action?.Invoke();
}
FTP上的其他方法
/// <summary>
/// 删除指定文件
/// </summary>
/// <param name="fileName"></param>
/// <param name="action"></param>
public async void RemoveFile(string fileName, UnityAction<bool> action = null)
{
await Task.Run(() =>
{
try
{
FtpWebRequest req = FtpWebRequest.Create(new Uri(FTP_PATH + "/" + fileName)) as FtpWebRequest;
req.Proxy = null;
NetworkCredential network = new NetworkCredential(USER_NAME, PASSWORD);
req.Credentials = network;
req.KeepAlive = false;
req.Method = WebRequestMethods.Ftp.DeleteFile;
req.UseBinary = true;
FtpWebResponse res = req.GetResponse() as FtpWebResponse;
res.Close();
action?.Invoke(true);
}
catch (Exception ex)
{
action?.Invoke(false);
Debug.LogException(ex);
}
});
}
/// <summary>
/// 获取FTP服务器上某个文件的大小
/// </summary>
/// <param name="fileName"></param>
/// <param name="action"></param>
public async void GetFileSize(string fileName, UnityAction<long> action = null)
{
await Task.Run(() =>
{
try
{
FtpWebRequest req = FtpWebRequest.Create(new Uri(FTP_PATH + "/" + fileName)) as FtpWebRequest;
req.Proxy = null;
NetworkCredential network = new NetworkCredential(USER_NAME, PASSWORD);
req.Credentials = network;
req.KeepAlive = false;
req.Method = WebRequestMethods.Ftp.GetFileSize;
req.UseBinary = true;
FtpWebResponse res = req.GetResponse() as FtpWebResponse;
action?.Invoke(res.ContentLength);
res.Close();
}
catch (Exception ex)
{
action?.Invoke(-1);
Debug.LogException(ex);
}
});
}
/// <summary>
/// 在FTP服务器上创建一个文件夹
/// </summary>
/// <param name="directoryName"></param>
/// <param name="action"></param>
public async void CreatDirectory(string directoryName, UnityAction<bool> action = null)
{
await Task.Run(() =>
{
try
{
FtpWebRequest req = FtpWebRequest.Create(new Uri(FTP_PATH + "/" + directoryName)) as FtpWebRequest;
req.Proxy = null;
NetworkCredential network = new NetworkCredential(USER_NAME, PASSWORD);
req.Credentials = network;
req.KeepAlive = false;
req.Method = WebRequestMethods.Ftp.MakeDirectory;
req.UseBinary = true;
FtpWebResponse res = req.GetResponse() as FtpWebResponse;
res.Close();
action?.Invoke(true);
}
catch (Exception ex)
{
action?.Invoke(false);
Debug.LogException(ex);
}
});
}
/// <summary>
/// 返回所有文件名
/// </summary>
/// <param name="directoryName"></param>
/// <param name="action"></param>
public async void GetFileList(string directoryName, UnityAction<List<string>> action = null)
{
await Task.Run(() =>
{
try
{
FtpWebRequest req = FtpWebRequest.Create(new Uri(FTP_PATH + "/" + directoryName)) as FtpWebRequest;
req.Proxy = null;
NetworkCredential network = new NetworkCredential(USER_NAME, PASSWORD);
req.Credentials = network;
req.KeepAlive = false;
req.Method = WebRequestMethods.Ftp.ListDirectory;
req.UseBinary = true;
FtpWebResponse res = req.GetResponse() as FtpWebResponse;
Stream s = res.GetResponseStream();
StreamReader sreader = new StreamReader(s);
List<string> list = new List<string>();
string line = sreader.ReadLine();
while (line != "")
{
list.Add(line);
line = sreader.ReadLine();
}
action?.Invoke(list);
sreader.Close();
s.Close();
res.Close();
}
catch (Exception ex)
{
action?.Invoke(new List<string>());
Debug.LogException(ex);
}
});
}
242

被折叠的 条评论
为什么被折叠?



