Unity网络开发--文件传输FTP

FTP的工作原理

  1. FTP 文件传输协议的本质是 TCP 通信

  2. FTP 有两种传输模式

    主动模式 (Port 模式) 和 被动模式 (Passive 模式)

  3. FTP 有两种传输方式

    ASCII 传输 和 二进制传输(建议使用)

  4. 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);
            }

        });
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值