当前位置: 首页 > news >正文

基于.NET Framework 4.0的FTP文件传输类

1. 核心技术原理

这个FTP客户端基于.NET Framework 4.0的System.Net命名空间,主要使用了:

  • FtpWebRequest:用于创建FTP请求
  • FtpWebResponse:接收FTP服务器响应
  • NetworkCredential:处理身份验证

2. 关键类组件说明

FtpClient类结构
- ftpServerIP: FTP服务器IP地址
- ftpUserID: 登录用户名
- ftpPassword: 登录密码
- ftpPort: FTP端口(默认21

3. 核心功能详解

上传文件 (UploadFile)
工作流程:
1. 构建FTP URI路径
2. 创建FtpWebRequest并设置为上传模式
3. 使用FileStream读取本地文件
4. 通过缓冲区分块传输数据
5. 完成后关闭所有流

关键设置:

  • UseBinary = true:使用二进制模式,确保文件完整性
  • KeepAlive = false:每次请求后关闭连接,避免超时
  • ContentLength:设置文件大小,让服务器知道传输量
  • 缓冲区2KB:平衡内存使用和传输效率
下载文件 (DownloadFile)
工作流程:
1. 创建下载请求
2. 获取服务器响应流
3. 创建本地文件(自动创建目录)
4. 分块读取并写入本地文件
5. 关闭所有资源

4. Linux兼容性考虑

  • 路径分隔符:Linux使用/,代码中远程路径使用正斜杠
  • 权限处理:确保FTP用户在Linux上有相应的读写权限
  • 编码问题:使用UTF-8编码处理文件名,支持中文
  • 二进制模式:避免Windows/Linux换行符差异

5. 错误处理机制

每个方法都包含完整的异常处理:

  • try-catch-finally结构确保资源释放
  • 返回布尔值表示操作成功/失败
  • 控制台输出错误信息便于调试

6. 性能优化要点

  1. 缓冲区大小:2KB适合大多数场景,可根据网络状况调整
  2. 超时设置:30秒超时避免长时间等待
  3. KeepAlive=false:避免连接池问题
  4. 资源管理:finally块确保流正确关闭

7. 安全性建议

  1. 加密传输:考虑使用FTPS(FTP over SSL)
  2. 凭据保护:不要硬编码密码,使用配置文件或加密存储
  3. 输入验证:验证文件路径防止路径遍历攻击
  4. 错误信息:生产环境避免暴露详细错误信息

8. 使用注意事项

Linux服务器配置
# 确保FTP服务运行
sudo service vsftpd status# 配置文件权限
chmod 755 /ftp/directory
chown ftpuser:ftpgroup /ftp/directory
防火墙设置
  • 开放21端口(控制连接)
  • 配置被动模式端口范围

9. 扩展建议

  1. 异步操作:对于大文件,考虑使用异步方法
  2. 进度报告:添加传输进度回调
  3. 断点续传:实现REST命令支持
  4. 连接池:频繁操作时维护连接池
using System;
using System.IO;
using System.Net;
using System.Text;namespace FtpFileTransfer
{/// <summary>/// FTP文件传输类,用于向Linux设备上传下载文件/// </summary>public class FtpClient{private string ftpServerIP;private string ftpUserID;private string ftpPassword;private int ftpPort;/// <summary>/// 构造函数/// </summary>/// <param name="serverIP">FTP服务器IP地址</param>/// <param name="userID">用户名</param>/// <param name="password">密码</param>/// <param name="port">端口号(默认21)</param>public FtpClient(string serverIP, string userID, string password, int port = 21){this.ftpServerIP = serverIP;this.ftpUserID = userID;this.ftpPassword = password;this.ftpPort = port;}/// <summary>/// 上传文件到FTP服务器/// </summary>/// <param name="localFilePath">本地文件完整路径</param>/// <param name="remoteFileName">远程文件名(包含路径)</param>/// <returns>上传是否成功</returns>public bool UploadFile(string localFilePath, string remoteFileName){FileInfo fileInfo = new FileInfo(localFilePath);string uri = string.Format("ftp://{0}:{1}/{2}", ftpServerIP, ftpPort, remoteFileName);FtpWebRequest request = null;FileStream fs = null;Stream requestStream = null;try{// 创建FTP请求request = (FtpWebRequest)WebRequest.Create(new Uri(uri));request.Credentials = new NetworkCredential(ftpUserID, ftpPassword);request.KeepAlive = false;request.Method = WebRequestMethods.Ftp.UploadFile;request.UseBinary = true;  // 二进制模式传输request.ContentLength = fileInfo.Length;request.Timeout = 30000;  // 30秒超时// 缓冲区大小设置为2KBint buffLength = 2048;byte[] buff = new byte[buffLength];int contentLen;// 打开本地文件流fs = fileInfo.OpenRead();// 获取FTP请求流requestStream = request.GetRequestStream();// 读取文件并写入FTP流contentLen = fs.Read(buff, 0, buffLength);while (contentLen != 0){requestStream.Write(buff, 0, contentLen);contentLen = fs.Read(buff, 0, buffLength);}Console.WriteLine("文件 {0} 上传成功", fileInfo.Name);return true;}catch (Exception ex){Console.WriteLine("上传文件时发生错误: " + ex.Message);return false;}finally{// 关闭流if (requestStream != null)requestStream.Close();if (fs != null)fs.Close();if (request != null)request.Abort();}}/// <summary>/// 从FTP服务器下载文件/// </summary>/// <param name="remoteFileName">远程文件名(包含路径)</param>/// <param name="localFilePath">本地保存路径</param>/// <returns>下载是否成功</returns>public bool DownloadFile(string remoteFileName, string localFilePath){string uri = string.Format("ftp://{0}:{1}/{2}", ftpServerIP, ftpPort, remoteFileName);FtpWebRequest request = null;FtpWebResponse response = null;Stream responseStream = null;FileStream outputStream = null;try{// 创建FTP请求request = (FtpWebRequest)WebRequest.Create(new Uri(uri));request.Method = WebRequestMethods.Ftp.DownloadFile;request.Credentials = new NetworkCredential(ftpUserID, ftpPassword);request.UseBinary = true;request.KeepAlive = false;request.Timeout = 30000;// 获取响应response = (FtpWebResponse)request.GetResponse();responseStream = response.GetResponseStream();// 创建本地文件string directoryPath = Path.GetDirectoryName(localFilePath);if (!Directory.Exists(directoryPath)){Directory.CreateDirectory(directoryPath);}outputStream = new FileStream(localFilePath, FileMode.Create);// 缓冲区byte[] buffer = new byte[2048];int readCount = responseStream.Read(buffer, 0, buffer.Length);// 读取并写入文件while (readCount > 0){outputStream.Write(buffer, 0, readCount);readCount = responseStream.Read(buffer, 0, buffer.Length);}Console.WriteLine("文件下载成功,保存到: {0}", localFilePath);return true;}catch (Exception ex){Console.WriteLine("下载文件时发生错误: " + ex.Message);return false;}finally{// 关闭流和响应if (outputStream != null)outputStream.Close();if (responseStream != null)responseStream.Close();if (response != null)response.Close();if (request != null)request.Abort();}}/// <summary>/// 获取FTP服务器上的文件列表/// </summary>/// <param name="remotePath">远程路径</param>/// <returns>文件列表</returns>public string[] GetFileList(string remotePath){string uri = string.Format("ftp://{0}:{1}/{2}", ftpServerIP, ftpPort, remotePath);try{FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri(uri));request.Credentials = new NetworkCredential(ftpUserID, ftpPassword);request.Method = WebRequestMethods.Ftp.ListDirectory;request.KeepAlive = false;FtpWebResponse response = (FtpWebResponse)request.GetResponse();StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);string line = reader.ReadLine();StringBuilder result = new StringBuilder();while (line != null){result.Append(line);result.Append("\n");line = reader.ReadLine();}reader.Close();response.Close();if (result.Length > 0){result.Remove(result.ToString().LastIndexOf('\n'), 1);return result.ToString().Split('\n');}else{return new string[] { };}}catch (Exception ex){Console.WriteLine("获取文件列表时发生错误: " + ex.Message);return new string[] { };}}/// <summary>/// 删除FTP服务器上的文件/// </summary>/// <param name="remoteFileName">远程文件名</param>/// <returns>删除是否成功</returns>public bool DeleteFile(string remoteFileName){string uri = string.Format("ftp://{0}:{1}/{2}", ftpServerIP, ftpPort, remoteFileName);try{FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri(uri));request.Credentials = new NetworkCredential(ftpUserID, ftpPassword);request.Method = WebRequestMethods.Ftp.DeleteFile;request.KeepAlive = false;FtpWebResponse response = (FtpWebResponse)request.GetResponse();response.Close();Console.WriteLine("文件 {0} 删除成功", remoteFileName);return true;}catch (Exception ex){Console.WriteLine("删除文件时发生错误: " + ex.Message);return false;}}/// <summary>/// 创建FTP服务器上的目录/// </summary>/// <param name="directoryName">目录名</param>/// <returns>创建是否成功</returns>public bool CreateDirectory(string directoryName){string uri = string.Format("ftp://{0}:{1}/{2}", ftpServerIP, ftpPort, directoryName);try{FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri(uri));request.Credentials = new NetworkCredential(ftpUserID, ftpPassword);request.Method = WebRequestMethods.Ftp.MakeDirectory;request.KeepAlive = false;FtpWebResponse response = (FtpWebResponse)request.GetResponse();response.Close();Console.WriteLine("目录 {0} 创建成功", directoryName);return true;}catch (Exception ex){Console.WriteLine("创建目录时发生错误: " + ex.Message);return false;}}/// <summary>/// 检查文件是否存在/// </summary>/// <param name="remoteFileName">远程文件名</param>/// <returns>文件是否存在</returns>public bool FileExists(string remoteFileName){string uri = string.Format("ftp://{0}:{1}/{2}", ftpServerIP, ftpPort, remoteFileName);try{FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri(uri));request.Credentials = new NetworkCredential(ftpUserID, ftpPassword);request.Method = WebRequestMethods.Ftp.GetFileSize;request.KeepAlive = false;FtpWebResponse response = (FtpWebResponse)request.GetResponse();response.Close();return true;}catch{return false;}}}/// <summary>/// 使用示例/// </summary>class Program{static void Main(string[] args){// 创建FTP客户端实例FtpClient ftpClient = new FtpClient("192.168.1.100",  // Linux服务器IP"username",        // FTP用户名"password",        // FTP密码21                 // FTP端口(默认21));// 上传文件示例bool uploadResult = ftpClient.UploadFile(@"C:\local\test.txt",           // 本地文件路径"/remote/path/test.txt"          // 远程文件路径);// 下载文件示例bool downloadResult = ftpClient.DownloadFile("/remote/path/test.txt",        // 远程文件路径@"C:\download\test.txt"          // 本地保存路径);// 获取文件列表string[] files = ftpClient.GetFileList("/remote/path/");foreach (string file in files){Console.WriteLine("文件: " + file);}// 检查文件是否存在bool exists = ftpClient.FileExists("/remote/path/test.txt");Console.WriteLine("文件存在: " + exists);// 创建目录ftpClient.CreateDirectory("/remote/newdir");// 删除文件ftpClient.DeleteFile("/remote/path/old.txt");Console.ReadLine();}}
}
http://www.dtcms.com/a/360744.html

相关文章:

  • 基于Hadoop的可视化城市宜居指数分析(代码+数据库+LW)
  • 【macOS】垃圾箱中文件无法清理的常规方法
  • Mac上如何安装mysql
  • MIT 6.5840 (Spring, 2024) 通关指南——Lab 2: Key/Value Server
  • 【Docker】Docker容器和镜像管理常用命令
  • Spring Bean 生命周期中的 @PostConstruct 注解
  • TCP实现线程池竞争任务
  • LeetCode Hot 100 Python (31~40)
  • 运动规划实战案例 | 基于行人社交模型的移动机器人动态避障(附ROS C++仿真)
  • Linux Tun/Tap 多队列技术
  • 【STM32】贪吃蛇 [阶段2](嵌入式进阶方向)
  • 【含文档+PPT+源码】基于SpringBoot+微信小程序的饮水健康之净水器保养管理系统设计与实现【包运行成功】
  • 【Linux】模拟实现Shell(下)
  • 打开模板打印
  • Ajax笔记(下)
  • 《探索C++11:现代C++语法的性能革新(上篇)》
  • 医疗AI时代的生物医学Go编程:高性能计算与精准医疗的案例分析(八)
  • Redis 核心概念解析:从渐进式遍历、数据库管理到客户端通信协议
  • 《C++进阶之STL》【红黑树】
  • C语言数据结构之双向链表
  • 基于 DNA 的原核生物与微小真核生物分类学:分子革命下的范式重构​
  • 【JavaWeb】之HTML(对HTML细节的一些总结)
  • Notepad++近期版本避雷
  • 【golang长途旅行第35站】Redis
  • Objective-C 的坚毅与传承:在Swift时代下的不可替代性优雅草卓伊凡
  • 云市场周报 (2025.09.01):解读腾讯云向量数据库、阿里云西安节点与平台工程
  • 从零开始的云计算生活——第五十五天,黑云压城,kubernetes模块之网络组件和CoreDNS组件
  • 数组(3)
  • Proteus8 仿真教学全指南:从入门到实战的电子开发利器
  • GitHub 热榜项目 - 日榜(2025-09-01)