44.FTP下载文件

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

×

喜欢就点赞,疼爱就打赏