44.网络通信-文件传输FTP-下载文件
44.1 知识点
使用FTP下载文件关键点
- 通信凭证:进行FTP连接操作时需要的账号密码。
- 操作命令:设置你想要进行的FTP操作。
- 文件流相关:上传和下载时都会使用的文件流。下载文件流使用FtpWebResponse类获取。
- 保证FTP服务器已经开启,并且能够正常访问。
FTP下载
try
{
// 创建一个Ftp连接。
// 这里和上传不同,上传的文件名是自己定义的,下载的文件名一定是资源服务器上有的,比如一张叫pic的图片。
FtpWebRequest ftpWebRequest = FtpWebRequest.Create(new Uri("ftp://127.0.0.1/pic.png")) as FtpWebRequest;
// 设置通信凭证(如果不支持匿名,就必须设置这一步)。
ftpWebRequest.Credentials = new NetworkCredential("MrTao", "MrTao");
// 请求完毕后是否关闭控制连接,如果要进行多次操作,可以设置为false。
ftpWebRequest.KeepAlive = false;
// 设置操作命令。
ftpWebRequest.Method = WebRequestMethods.Ftp.DownloadFile;
// 指定传输类型。
ftpWebRequest.UseBinary = true;
// 代理设置为空。
ftpWebRequest.Proxy = null;
// 得到用于下载的流对象。
// 相当于把请求发送给FTP服务器,返回值就会携带我们想要的信息。
FtpWebResponse ftpWebResponse = ftpWebRequest.GetResponse() as FtpWebResponse;
// 这就是下载的流。
Stream downloadResponseStream = ftpWebResponse.GetResponseStream();
// 开始下载。
print(Application.persistentDataPath);
using (FileStream fileStream = File.Create(Application.persistentDataPath + "/pic2.png"))
{
// 读取流的字节数组。
byte[] bytes = new byte[1024];
// 读取下载下来的流数据。
int contentLength = downloadResponseStream.Read(bytes, 0, bytes.Length);
// 一点一点的下载到本地流中。
while (contentLength != 0)
{
// 把读取出来的字节数组写入到本地文件流中。
fileStream.Write(bytes, 0, contentLength);
// 继续读。
contentLength = downloadResponseStream.Read(bytes, 0, bytes.Length);
}
// 下载结束,关闭流。
downloadResponseStream.Close();
fileStream.Close();
}
print("下载结束");
}
catch (Exception e)
{
print("下载出错" + e.Message);
}
开启服务器,挂载脚本后可以成功下载到本地。
总结
C#已经把FTP相关操作封装的很好了,我们只需要熟悉API,直接使用它们进行FTP下载即可。我们主要做的操作是把下载文件的FTP流读出字节数据写入到本地文件流中。
44.2 知识点代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using UnityEngine;
public class Lesson44_网络通信_文件传输FTP_下载文件 : MonoBehaviour
{
void Start()
{
#region 知识点一 使用FTP下载文件关键点
//1.通信凭证
// 进行Ftp连接操作时需要的账号密码
//2.操作命令 WebRequestMethods.Ftp
// 设置你想要进行的Ftp操作
//3.文件流相关 FileStream 和 Stream
// 上传和下载时都会使用的文件流
// 下载文件流使用FtpWebResponse类获取
//4.保证FTP服务器已经开启
// 并且能够正常访问
#endregion
#region 知识点二 FTP下载
try
{
//1.创建一个Ftp连接
//这里和上传不同,上传的文件名 是自己定义的 下载的文件名 一定是资源服务器上有的 比如一张叫pic的图片
FtpWebRequest ftpWebRequest = FtpWebRequest.Create(new Uri("ftp://127.0.0.1/pic.png")) as FtpWebRequest;
//2.设置通信凭证(如果不支持匿名 就必须设置这一步)
ftpWebRequest.Credentials = new NetworkCredential("MrTao", "MrTao");
//请求完毕后 是否关闭控制连接,如果要进行多次操作 可以设置为false
ftpWebRequest.KeepAlive = false;
//3.设置操作命令
ftpWebRequest.Method = WebRequestMethods.Ftp.DownloadFile;
//4.指定传输类型
ftpWebRequest.UseBinary = true;
//代理设置为空
ftpWebRequest.Proxy = null;
//5.得到用于下载的流对象
//相当于把请求发送给FTP服务器 返回值 就会携带我们想要的信息
FtpWebResponse ftpWebResponse = ftpWebRequest.GetResponse() as FtpWebResponse;
//这就是下载的流
Stream downloadResponseStream = ftpWebResponse.GetResponseStream();
//6.开始下载
print(Application.persistentDataPath);
using (FileStream fileStream = File.Create(Application.persistentDataPath + "/pic2.png"))
{
//读取流的字节数组
byte[] bytes = new byte[1024];
//读取下载下来的流数据
int contentLength = downloadResponseStream.Read(bytes, 0, bytes.Length);
//一点一点的 下载到本地流中
while (contentLength != 0)
{
//把读取出来的字节数组 写入到本地文件流中
fileStream.Write(bytes, 0, contentLength);
//那我们继续读
contentLength = downloadResponseStream.Read(bytes, 0, bytes.Length);
}
//下载结束 关闭流
downloadResponseStream.Close();
fileStream.Close();
}
print("下载结束");
}
catch (Exception e)
{
print("下载出错" + e.Message);
}
#endregion
#region 总结
//C#已经把Ftp相关操作封装的很好了
//我们只需要熟悉API,直接使用他们进行FTP下载即可
//我们主要做的操作是
//把下载文件的FTP流读出字节数据写入到本地文件流中
#endregion
}
}
44.3 练习题
在之前的Ftp管理器当中,封装一个下载相关方法,同样还是以多线程进行下载,避免影响主线程逻辑
在FTP管理器添加异步下载文件方法
/// <summary>
/// 下载文件从Ftp服务器当中(异步)
/// </summary>
/// <param name="fileName">FTP上想要下载的文件名</param>
/// <param name="localPath">存储的本地文件路径</param>
/// <param name="action">下载完毕后想要做什么的委托函数</param>
public async void DownLoadFile(string fileName, string localPath, UnityAction action = null)
{
await Task.Run(() => {
try
{
//1.创建一个Ftp连接
FtpWebRequest ftpWebRequest = FtpWebRequest.Create(new Uri(FTP_PATH + fileName)) as FtpWebRequest;
//2.进行一些设置
//凭证
ftpWebRequest.Credentials = new NetworkCredential(USER_NAME, PASSWORD);
//是否操作结束后 关闭 控制连接
ftpWebRequest.KeepAlive = false;
//传输类型
ftpWebRequest.UseBinary = true;
//操作类型
ftpWebRequest.Method = WebRequestMethods.Ftp.DownloadFile;
//代理设置为空
ftpWebRequest.Proxy = null;
//3.下载
FtpWebResponse ftpWebResponse = ftpWebRequest.GetResponse() as FtpWebResponse;
Stream downloadResponseStream = ftpWebResponse.GetResponseStream();
//写入到本地文件中
using (FileStream fileStream = File.Create(localPath))
{
byte[] bytes = new byte[1024];
//读取数据
int contentLength = downloadResponseStream.Read(bytes, 0, bytes.Length);
//一点一点的写入
while (contentLength != 0)
{
//读多少 写多少
fileStream.Write(bytes, 0, contentLength);
//继续读
contentLength = downloadResponseStream.Read(bytes, 0, bytes.Length);
}
fileStream.Close();
downloadResponseStream.Close();
}
Debug.Log("下载成功");
}
catch (Exception e)
{
Debug.Log("下载失败" + e.Message);
}
});
//如果下载结束有想做的事情 在这里调用外部传入的委托函数
action?.Invoke();
}
开启服务器挂载测试脚本,测试下载上节课练习题上传的图片
print(Application.persistentDataPath);
FtpManager.Instance.DownLoadFile("MrTaoPic.png", Application.persistentDataPath + "/MrTaoPic666.png", () =>
{
print("下载结束 调用委托函数");
});
print("测试测试");
44.4 练习题代码
FtpManager
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 FtpManager : BaseSingletonInCSharp<FtpManager>
{
//远端FTP服务器的地址 这里用本机来测试
private string FTP_PATH = "ftp://127.0.0.1/";
//用户名和密码
private string USER_NAME = "MrTao";
private string PASSWORD = "MrTao";
/// <summary>
/// 上传文件到Ftp服务器(异步)
/// </summary>
/// <param name="fileName">FTP上的文件名</param>
/// <param name="localPath">本地文件路径</param>
/// <param name="action">上传完毕后想要做什么的委托函数</param>
public async void UpLoadFile(string fileName, string localPath, UnityAction action = null)
{
//异步任务
await Task.Run(() =>
{
try
{
//通过一个线程执行这里面的逻辑 那么就不会影响主线程了
//1.创建一个Ftp连接
FtpWebRequest ftpWebRequest = FtpWebRequest.Create(new Uri(FTP_PATH + fileName)) as FtpWebRequest;
//2.进行一些设置
//凭证
ftpWebRequest.Credentials = new NetworkCredential(USER_NAME, PASSWORD);
//是否操作结束后 关闭 控制连接
ftpWebRequest.KeepAlive = false;
//传输类型
ftpWebRequest.UseBinary = true;
//操作类型
ftpWebRequest.Method = WebRequestMethods.Ftp.UploadFile;
//代理设置为空
ftpWebRequest.Proxy = null;
//3.上传
Stream uploadRequestStream = ftpWebRequest.GetRequestStream();
//开始上传
using (FileStream fileStream = File.OpenRead(localPath))
{
byte[] bytes = new byte[1024];
//返回值 为具体读取了多少个字节
int contentLength = fileStream.Read(bytes, 0, bytes.Length);
//有数据就上传
while (contentLength != 0)
{
//读了多少就写(上传)多少
uploadRequestStream.Write(bytes, 0, contentLength);
//继续从本地文件中读取数据
contentLength = fileStream.Read(bytes, 0, bytes.Length);
}
//上传结束
fileStream.Close();
uploadRequestStream.Close();
}
Debug.Log("上传成功");
}
catch (Exception e)
{
Debug.Log("上传文件出错" + e.Message);
}
});
//上传结束后 你想在外部做的事情
action?.Invoke();
}
/// <summary>
/// 下载文件从Ftp服务器当中(异步)
/// </summary>
/// <param name="fileName">FTP上想要下载的文件名</param>
/// <param name="localPath">存储的本地文件路径</param>
/// <param name="action">下载完毕后想要做什么的委托函数</param>
public async void DownLoadFile(string fileName, string localPath, UnityAction action = null)
{
await Task.Run(() => {
try
{
//1.创建一个Ftp连接
FtpWebRequest ftpWebRequest = FtpWebRequest.Create(new Uri(FTP_PATH + fileName)) as FtpWebRequest;
//2.进行一些设置
//凭证
ftpWebRequest.Credentials = new NetworkCredential(USER_NAME, PASSWORD);
//是否操作结束后 关闭 控制连接
ftpWebRequest.KeepAlive = false;
//传输类型
ftpWebRequest.UseBinary = true;
//操作类型
ftpWebRequest.Method = WebRequestMethods.Ftp.DownloadFile;
//代理设置为空
ftpWebRequest.Proxy = null;
//3.下载
FtpWebResponse ftpWebResponse = ftpWebRequest.GetResponse() as FtpWebResponse;
Stream downloadResponseStream = ftpWebResponse.GetResponseStream();
//写入到本地文件中
using (FileStream fileStream = File.Create(localPath))
{
byte[] bytes = new byte[1024];
//读取数据
int contentLength = downloadResponseStream.Read(bytes, 0, bytes.Length);
//一点一点的写入
while (contentLength != 0)
{
//读多少 写多少
fileStream.Write(bytes, 0, contentLength);
//继续读
contentLength = downloadResponseStream.Read(bytes, 0, bytes.Length);
}
fileStream.Close();
downloadResponseStream.Close();
}
Debug.Log("下载成功");
}
catch (Exception e)
{
Debug.Log("下载失败" + e.Message);
}
});
//如果下载结束有想做的事情 在这里调用外部传入的委托函数
action?.Invoke();
}
}
Lesson44_练习题
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson44_练习题 : MonoBehaviour
{
void Start()
{
print(Application.persistentDataPath);
FtpManager.Instance.DownLoadFile("MrTaoPic.png", Application.persistentDataPath + "/MrTaoPic666.png", () =>
{
print("下载结束 调用委托函数");
});
print("测试测试");
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com