C# FTP操作類

来源:http://www.cnblogs.com/Liyuting/archive/2017/06/27/7084718.html
-Advertisement-
Play Games

可進行FTP的上傳,下載等其他功能,支持斷點續傳: using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; usi ...


可進行FTP的上傳,下載等其他功能,支持斷點續傳:

 

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace ManagementProject
{
    public class FTPHelper
    {
        string ftpRemotePath;

        #region 變數屬性
        /// <summary>
        /// Ftp伺服器ip
        /// </summary>
        public static string FtpServerIP = "";
        /// <summary>
        /// Ftp 指定用戶名
        /// </summary>
        public static string FtpUserID = "";
        /// <summary>
        /// Ftp 指定用戶密碼
        /// </summary>
        public static string FtpPassword = "";

        public static string ftpURI = "ftp://" + FtpServerIP + "/";

        #endregion

        #region 從FTP伺服器下載文件,指定本地路徑和本地文件名
        /// <summary>
        /// 從FTP伺服器下載文件,指定本地路徑和本地文件名
        /// </summary>
        /// <param name="remoteFileName">遠程文件名</param>
        /// <param name="localFileName">保存本地的文件名(包含路徑)</param>
        /// <param name="ifCredential">是否啟用身份驗證(false:表示允許用戶匿名下載)</param>
        /// <param name="updateProgress">報告進度的處理(第一個參數:總大小,第二個參數:當前進度)</param>
        /// <returns>是否下載成功</returns>
        public static bool FtpDownload(string remoteFileName, string localFileName, bool ifCredential, Action<int, int> updateProgress = null)
        {
            FtpWebRequest reqFTP, ftpsize;
            Stream ftpStream = null;
            FtpWebResponse response = null;
            FileStream outputStream = null;
            try
            {

                outputStream = new FileStream(localFileName, FileMode.Create);
                if (FtpServerIP == null || FtpServerIP.Trim().Length == 0)
                {
                    throw new Exception("ftp下載目標伺服器地址未設置!");
                }
                Uri uri = new Uri("ftp://" + FtpServerIP + "/" + remoteFileName);
                ftpsize = (FtpWebRequest)FtpWebRequest.Create(uri);
                ftpsize.UseBinary = true;

                reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri);
                reqFTP.UseBinary = true;
                reqFTP.KeepAlive = false;
                if (ifCredential)//使用用戶身份認證
                {
                    ftpsize.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
                    reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
                }
                ftpsize.Method = WebRequestMethods.Ftp.GetFileSize;
                FtpWebResponse re = (FtpWebResponse)ftpsize.GetResponse();
                long totalBytes = re.ContentLength;
                re.Close();

                reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
                response = (FtpWebResponse)reqFTP.GetResponse();
                ftpStream = response.GetResponseStream();

                //更新進度  
                if (updateProgress != null)
                {
                    updateProgress((int)totalBytes, 0);//更新進度條   
                }
                long totalDownloadedByte = 0;
                int bufferSize = 2048;
                int readCount;
                byte[] buffer = new byte[bufferSize];
                readCount = ftpStream.Read(buffer, 0, bufferSize);
                while (readCount > 0)
                {
                    totalDownloadedByte = readCount + totalDownloadedByte;
                    outputStream.Write(buffer, 0, readCount);
                    //更新進度  
                    if (updateProgress != null)
                    {
                        updateProgress((int)totalBytes, (int)totalDownloadedByte);//更新進度條   
                    }
                    readCount = ftpStream.Read(buffer, 0, bufferSize);
                }
                ftpStream.Close();
                outputStream.Close();
                response.Close();
                return true;
            }
            catch (Exception ex)
            {
                return false;
                throw;
            }
            finally
            {
                if (ftpStream != null)
                {
                    ftpStream.Close();
                }
                if (outputStream != null)
                {
                    outputStream.Close();
                }
                if (response != null)
                {
                    response.Close();
                }
            }
        }
        /// <summary>
        /// 從FTP伺服器下載文件,指定本地路徑和本地文件名(支持斷點下載)
        /// </summary>
        /// <param name="remoteFileName">遠程文件名</param>
        /// <param name="localFileName">保存本地的文件名(包含路徑)</param>
        /// <param name="ifCredential">是否啟用身份驗證(false:表示允許用戶匿名下載)</param>
        /// <param name="size">已下載文件流大小</param>
        /// <param name="updateProgress">報告進度的處理(第一個參數:總大小,第二個參數:當前進度)</param>
        /// <returns>是否下載成功</returns>
        public static bool FtpBrokenDownload(string remoteFileName, string localFileName, bool ifCredential, long size, Action<int, int> updateProgress = null)
        {
            FtpWebRequest reqFTP, ftpsize;
            Stream ftpStream = null;
            FtpWebResponse response = null;
            FileStream outputStream = null;
            try
            {

                outputStream = new FileStream(localFileName, FileMode.Append);
                if (FtpServerIP == null || FtpServerIP.Trim().Length == 0)
                {
                    throw new Exception("ftp下載目標伺服器地址未設置!");
                }
                Uri uri = new Uri("ftp://" + FtpServerIP + "/" + remoteFileName);
                ftpsize = (FtpWebRequest)FtpWebRequest.Create(uri);
                ftpsize.UseBinary = true;
                ftpsize.ContentOffset = size;

                reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri);
                reqFTP.UseBinary = true;
                reqFTP.KeepAlive = false;
                reqFTP.ContentOffset = size;
                if (ifCredential)//使用用戶身份認證
                {
                    ftpsize.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
                    reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
                }
                ftpsize.Method = WebRequestMethods.Ftp.GetFileSize;
                FtpWebResponse re = (FtpWebResponse)ftpsize.GetResponse();
                long totalBytes = re.ContentLength;
                re.Close();

                reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
                response = (FtpWebResponse)reqFTP.GetResponse();
                ftpStream = response.GetResponseStream();

                //更新進度  
                if (updateProgress != null)
                {
                    updateProgress((int)totalBytes, 0);//更新進度條   
                }
                long totalDownloadedByte = 0;
                int bufferSize = 2048;
                int readCount;
                byte[] buffer = new byte[bufferSize];
                readCount = ftpStream.Read(buffer, 0, bufferSize);
                while (readCount > 0)
                {
                    totalDownloadedByte = readCount + totalDownloadedByte;
                    outputStream.Write(buffer, 0, readCount);
                    //更新進度  
                    if (updateProgress != null)
                    {
                        updateProgress((int)totalBytes, (int)totalDownloadedByte);//更新進度條   
                    }
                    readCount = ftpStream.Read(buffer, 0, bufferSize);
                }
                ftpStream.Close();
                outputStream.Close();
                response.Close();
                return true;
            }
            catch (Exception ex)
            {
                return false;
                throw;
            }
            finally
            {
                if (ftpStream != null)
                {
                    ftpStream.Close();
                }
                if (outputStream != null)
                {
                    outputStream.Close();
                }
                if (response != null)
                {
                    response.Close();
                }
            }
        }

        /// <summary>
        /// 從FTP伺服器下載文件,指定本地路徑和本地文件名
        /// </summary>
        /// <param name="remoteFileName">遠程文件名</param>
        /// <param name="localFileName">保存本地的文件名(包含路徑)</param>
        /// <param name="ifCredential">是否啟用身份驗證(false:表示允許用戶匿名下載)</param>
        /// <param name="updateProgress">報告進度的處理(第一個參數:總大小,第二個參數:當前進度)</param>
        /// <param name="brokenOpen">是否斷點下載:true 會在localFileName 找是否存在已經下載的文件,並計算文件流大小</param>
        /// <returns>是否下載成功</returns>
        public static bool FtpDownload(string remoteFileName, string localFileName, bool ifCredential, bool brokenOpen, Action<int, int> updateProgress = null)
        {
            if (brokenOpen)
            {
                try
                {
                    long size = 0;
                    if (File.Exists(localFileName))
                    {
                        using (FileStream outputStream = new FileStream(localFileName, FileMode.Open))
                        {
                            size = outputStream.Length;
                        }
                    }
                    return FtpBrokenDownload(remoteFileName, localFileName, ifCredential, size, updateProgress);
                }
                catch
                {
                    throw;
                }
            }
            else
            {
                return FtpDownload(remoteFileName, localFileName, ifCredential, updateProgress);
            }
        }
        #endregion

        #region 上傳文件到FTP伺服器
        /// <summary>
        /// 上傳文件到FTP伺服器
        /// </summary>
        /// <param name="localFullPath">本地帶有完整路徑的文件名</param>
        /// <param name="updateProgress">報告進度的處理(第一個參數:總大小,第二個參數:當前進度)</param>
        /// <returns>是否下載成功</returns>
        public static bool FtpUploadFile(string localFullPathName, Action<int, int> updateProgress = null)
        {
            FtpWebRequest reqFTP;
            Stream stream = null;
            FtpWebResponse response = null;
            FileStream fs = null;
            try
            {
                FileInfo finfo = new FileInfo(localFullPathName);
                if (FtpServerIP == null || FtpServerIP.Trim().Length == 0)
                {
                    throw new Exception("ftp上傳目標伺服器地址未設置!");
                }
                Uri uri = new Uri("ftp://" + FtpServerIP + "/" + finfo.Name);
                reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri);
                reqFTP.KeepAlive = false;
                reqFTP.UseBinary = true;
                reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);//用戶,密碼
                reqFTP.Method = WebRequestMethods.Ftp.UploadFile;//向伺服器發出下載請求命令
                reqFTP.ContentLength = finfo.Length;//為request指定上傳文件的大小
                response = reqFTP.GetResponse() as FtpWebResponse;
                reqFTP.ContentLength = finfo.Length;
                int buffLength = 1024;
                byte[] buff = new byte[buffLength];
                int contentLen;
                fs = finfo.OpenRead();
                stream = reqFTP.GetRequestStream();
                contentLen = fs.Read(buff, 0, buffLength);
                int allbye = (int)finfo.Length;
                //更新進度  
                if (updateProgress != null)
                {
                    updateProgress((int)allbye, 0);//更新進度條   
                }
                int startbye = 0;
                while (contentLen != 0)
                {
                    startbye = contentLen + startbye;
                    stream.Write(buff, 0, contentLen);
                    //更新進度  
                    if (updateProgress != null)
                    {
                        updateProgress((int)allbye, (int)startbye);//更新進度條   
                    }
                    contentLen = fs.Read(buff, 0, buffLength);
                }
                stream.Close();
                fs.Close();
                response.Close();
                return true;

            }
            catch (Exception ex)
            {
                return false;
                throw;
            }
            finally
            {
                if (fs != null)
                {
                    fs.Close();
                }
                if (stream != null)
                {
                    stream.Close();
                }
                if (response != null)
                {
                    response.Close();
                }
            }
        }

        /// <summary>
        /// 上傳文件到FTP伺服器(斷點續傳)
        /// </summary>
        /// <param name="localFullPath">本地文件全路徑名稱:C:\Users\JianKunKing\Desktop\IronPython腳本測試工具</param>
        /// <param name="remoteFilepath">遠程文件所在文件夾路徑</param>
        /// <param name="updateProgress">報告進度的處理(第一個參數:總大小,第二個參數:當前進度)</param>
        /// <returns></returns>       
        public static bool FtpUploadBroken(string localFullPath, string remoteFilepath, Action<int, int> updateProgress = null)
        {
            if (remoteFilepath == null)
            {
                remoteFilepath = "";
            }
            string newFileName = string.Empty;
            bool success = true;
            FileInfo fileInf = new FileInfo(localFullPath);
            long allbye = (long)fileInf.Length;
            if (fileInf.Name.IndexOf("#") == -1)
            {
                newFileName = RemoveSpaces(fileInf.Name);
            }
            else
            {
                newFileName = fileInf.Name.Replace("#", "");
                newFileName = RemoveSpaces(newFileName);
            }
            long startfilesize = GetFileSize(newFileName, remoteFilepath);
            if (startfilesize >= allbye)
            {
                return false;
            }
            long startbye = startfilesize;
            //更新進度  
            if (updateProgress != null)
            {
                updateProgress((int)allbye, (int)startfilesize);//更新進度條   
            }

            string uri;
            if (remoteFilepath.Length == 0)
            {
                uri = "ftp://" + FtpServerIP + "/" + newFileName;
            }
            else
            {
                uri = "ftp://" + FtpServerIP + "/" + remoteFilepath + "/" + newFileName;
            }
            FtpWebRequest reqFTP;
            // 根據uri創建FtpWebRequest對象 
            reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
            // ftp用戶名和密碼 
            reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
            // 預設為true,連接不會被關閉 
            // 在一個命令之後被執行 
            reqFTP.KeepAlive = false;
            // 指定執行什麼命令 
            reqFTP.Method = WebRequestMethods.Ftp.AppendFile;
            // 指定數據傳輸類型 
            reqFTP.UseBinary = true;
            // 上傳文件時通知伺服器文件的大小 
            reqFTP.ContentLength = fileInf.Length;
            int buffLength = 2048;// 緩衝大小設置為2kb 
            byte[] buff = new byte[buffLength];
            // 打開一個文件流 (System.IO.FileStream) 去讀上傳的文件 
            FileStream fs = fileInf.OpenRead();
            Stream strm = null;
            try
            {
                // 把上傳的文件寫入流 
                strm = reqFTP.GetRequestStream();
                // 每次讀文件流的2kb   
                fs.Seek(startfilesize, 0);
                int contentLen = fs.Read(buff, 0, buffLength);
                // 流內容沒有結束 
                while (contentLen != 0)
                {
                    // 把內容從file stream 寫入 upload stream 
                    strm.Write(buff, 0, contentLen);
                    contentLen = fs.Read(buff, 0, buffLength);
                    startbye += contentLen;
                    //更新進度  
                    if (updateProgress != null)
                    {
                        updateProgress((int)allbye, (int)startbye);//更新進度條   
                    }
                }
                // 關閉兩個流 
                strm.Close();
                fs.Close();
            }
            catch
            {
                success = false;
                throw;
            }
            finally
            {
                if (fs != null)
                {
                    fs.Close();
                }
                if (strm != null)
                {
                    strm.Close();
                }
            }
            return success;
        }

        /// <summary>
        /// 去除空格
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private static string RemoveSpaces(string str)
        {
            string a = "";
            CharEnumerator CEnumerator = str.GetEnumerator();
            while (CEnumerator.MoveNext())
            {
                byte[] array = new byte[1];
                array = System.Text.Encoding.ASCII.GetBytes(CEnumerator.Current.ToString());
                int asciicode = (short)(array[0]);
                if (asciicode != 32)
                {
                    a += CEnumerator.Current.ToString();
                }
            }
            string sdate = System.DateTime.Now.Year.ToString() + System.DateTime.Now.Month.ToString() + System.DateTime.Now.Day.ToString() + System.DateTime.Now.Hour.ToString()
                + System.DateTime.Now.Minute.ToString() + System.DateTime.Now.Second.ToString() + System.DateTime.Now.Millisecond.ToString();
            return a.Split('.')[a.Split('.').Length - 2] + "." + a.Split('.')[a.Split('.').Length - 1];
        }
        /// <summary>
        /// 獲取已上傳文件大小
        /// </summary>
        /// <param name="filename">文件名稱</param>
        /// <param name="path">伺服器文件路徑</param>
        /// <returns></returns>
        public static long GetFileSize(string filename, string remoteFilepath)
        {
            long filesize = 0;
            try
            {
                FtpWebRequest reqFTP;
                FileInfo fi = new FileInfo(filename);
                string uri;
                if (remoteFilepath.Length == 0)
                {
                    uri = "ftp://" + FtpServerIP + "/" + fi.Name;
                }
                else
                {
                    uri = "ftp://" + FtpServerIP + "/" + remoteFilepath + "/" + fi.Name;
                }
                reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri);
                reqFTP.KeepAlive = false;
                reqFTP.UseBinary = true;
                reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);//用戶,密碼
                reqFTP.Method = WebRequestMethods.Ftp.GetFileSize;
                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
                filesize = response.ContentLength;
                return filesize;
            }
            catch
            {
                return 0;
            }
        }

        //public void Connect(String path, string ftpUserID, string ftpPassword)//連接ftp
        //{
        //    // 根據uri創建FtpWebRequest對象
        //    reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(path));
        //    // 指定數據傳輸類型
        //    reqFTP.UseBinary = true;
        //    // ftp用戶名和密碼
        //    reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
        //}

        #endregion

        #region 獲取當前目錄下明細
        /// <summary>
        /// 獲取當前目錄下明細(包含文件和文件夾)
        /// </summary>
        /// <returns></returns>
        public static string[] GetFilesDetailList()
        {
            string[] downloadFiles;
            try
            {
                StringBuilder result = new StringBuilder();
                FtpWebRequest ftp;
                ftp = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpURI));
                ftp.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
                ftp.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
                WebResponse response = ftp.GetResponse();
                StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.Default);
                string line = reader.ReadLine();

                while (line != null)
                {
                    result.Append(line);
                    result.Append("\n");
                    line = reader.ReadLine();
                }
                result.Remove(result.ToString().LastIndexOf("\n"), 1);
                reader.Close();
                response.Close();
                return result.ToString().Split('\n');
            }
            catch (Exception ex)
            {
                downloadFiles = null;
                throw ex;
            }
        }

        /// <summary>
        /// 獲取當前目錄下文件列表(僅文件)
        /// </summary>
        /// <returns></returns>
        public static string[] GetFileList(string mask)
        {
            string[] downloadFiles;
            StringBuilder result = new StringBuilder();
            FtpWebRequest reqFTP;
            try
            {
                reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpURI));
                reqFTP.UseBinary = true;
                reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
                reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
                WebResponse response = reqFTP.GetResponse();
                StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.Default);

                string line = reader.ReadLine();
                while (line != null)
                {
                    if (mask.Trim() != string.Empty && mask.Trim() != "*.*")
                    {

                        string mask_ = mask.Substring(0, mask.IndexOf("*"));
                        if (line.Substring(0, mask_.Length) == mask_)
                        {
                            result.Append(line);
                            result.Append("\n");
                        }
                    }
                    else
                    {
                        result.Append(line);
                        result.Append("\n");
                    }
                    line = reader.ReadLine();
                }
                result.Remove(result.ToString().LastIndexOf('\n'), 1);
                reader.Close();
                response.Close();
                return result.ToString().Split('\n');
            }
            catch (Exception ex)
            {
                downloadFiles = null;
                throw ex;
            }
        }

        /// <summary>
        /// 獲取當前目錄下所有的文件夾列表(僅文件夾)
        /// </summary>
        /// <returns></returns>
        public static string[] GetDirectoryList()
        {
            string[] drectory = GetFilesDetailList();
            string m = string.Empty;
            foreach (string str in drectory)
            {
                int dirPos = str.IndexOf("<DIR>");
                if (dirPos > 0)
                {
                    /*判斷 Windows 風格*/
                    m += str.Substring(dirPos + 5).Trim() + "\n";
                }
                else if (str.Trim().Substring(0, 1).ToUpper() == "D"	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • “System.InvalidOperationException”類型的未經處理的異常在 mscorlib.dll 中發生 其他信息: 無法為具有固定名稱“MySql.Data.MySqlClient”的 ADO.NET 提供程式載入在應用程式配置文件中註冊的實體框架提供程式類型“MySql.Da ...
  • using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Reflection; using System.Collections; using System. ...
  • using System; using System.IO; using System.Text; using System.Xml; using System.Xml.Serialization; //using System.Runtime.Serialization.Json; using S ...
  • using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Reflection; using System.Collections; using System. ...
  • 下拉框聯動效果,我們以部門--職位為例,選擇部門時,關聯到該部門的職位.下拉框的寫法就不多說了,詳細請參照前文. 視圖: 其中,dept是部門的屬性,deptlist是部門下拉框的屬性,job是職位的屬性,joblist是職位下拉框的屬性,下拉框綁定請參照前文 當部門變動的時候,職位也相應改變: 執 ...
  • using System; using System.Collections; using System.IO; using System.Drawing; using System.Drawing.Imaging; using System.Drawing.Drawing2D; namespace ...
  • using System.Web; using System.Configuration; namespace DotNet.Utilities { public class VideoConvert : System.Web.UI.Page { public VideoConvert() { } ...
  • 1.Model 2.cotroller 3.View ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...