场景
Windows10上怎样开启FTP服务:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/121617773
上面在Windows上搭建FTP服务器之后,会接收客户端发来的文件并存储在指定目录下,
需要在此台服务器上再搭建一个FTP客户端实现定时扫描指定路径下的文件,并将这些文件
上传到另一个FTP服务端,上传成功之后将这些文件删除,实现文件中转操作。
找到上面搭建的网站下的FTP身份验证,双击
将匿名访问关闭,开启身份认证
注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。
实现
1、Windows上创建一个新用户
控制面板-账户-家庭和其他用户-将其他人添加到这台电脑
2、选择我没有这个人的登录信息
3、选择添加一个没有账户的用户
4、然后创建用户名、密码、和安全问题等。
5、新建一个Winform项目,设计主页面布局
6、实现建立连接和列出所有文件的功能
首先新建FtpHelper工具类,该工具类来源与网络,并对其进行少量修改。
FtpHelper.cs
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Threading; using System.Threading.Tasks; namespace UploadFtpServerSchedule { public class FtpHelper { #region 属性与构造函数 /// <summary> /// IP地址 /// </summary> public string IpAddr { get; set; } /// <summary> /// 相对路径 /// </summary> public string RelatePath { get; set; } /// <summary> /// 端口号 /// </summary> public string Port { get; set; } /// <summary> /// 用户名 /// </summary> public string UserName { get; set; } /// <summary> /// 密码 /// </summary> public string Password { get; set; } public FtpHelper() { } public FtpHelper(string ipAddr, string port, string userName, string password) { this.IpAddr = ipAddr; this.Port = port; this.UserName = userName; this.Password = password; } #endregion #region 方法 /// <summary> /// 下载文件 /// </summary> /// <param name="filePath"></param> /// <param name="isOk"></param> public void DownLoad(string filePath, out bool isOk) { string method = WebRequestMethods.Ftp.DownloadFile; var statusCode = FtpStatusCode.DataAlreadyOpen; FtpWebResponse response = callFtp(method); ReadByBytes(filePath, response, statusCode, out isOk); } public void UpLoad(string file, out bool isOk,string filename) { isOk = false; FileInfo fi = new FileInfo(file); FileStream fs = fi.OpenRead(); long length = fs.Length; string uri = string.Format("ftp://{0}:{1}/{2}", this.IpAddr, this.Port, filename); FtpWebRequest request = (FtpWebRequest)WebRequest.Create(uri); request.Credentials = new NetworkCredential(UserName, Password); request.Method = WebRequestMethods.Ftp.UploadFile; request.UseBinary = true; request.ContentLength = length; request.Timeout = 10 * 1000; try { Stream stream = request.GetRequestStream(); int BufferLength = 2048; //2K byte[] b = new byte[BufferLength]; int i; while ((i = fs.Read(b, 0, BufferLength)) > 0) { stream.Write(b, 0, i); } stream.Close(); stream.Dispose(); fs.Close(); isOk = true; } catch (Exception ex) { Console.WriteLine(ex.ToString()); } finally { if (request != null) { request.Abort(); request = null; } } } /// <summary> /// 删除文件 /// </summary> /// <param name="isOk"></param> /// <returns></returns> public string[] DeleteFile(out bool isOk) { string method = WebRequestMethods.Ftp.DeleteFile; var statusCode = FtpStatusCode.FileActionOK; FtpWebResponse response = callFtp(method); return ReadByLine(response, statusCode, out isOk); } /// <summary> /// 展示目录 /// </summary> public string[] ListDirectory(out bool isOk) { string method = WebRequestMethods.Ftp.ListDirectoryDetails; var statusCode = FtpStatusCode.DataAlreadyOpen; FtpWebResponse response = callFtp(method); return ReadByLine(response, statusCode, out isOk); } /// <summary> /// 设置上级目录 /// </summary> public void SetPrePath() { string relatePath = this.RelatePath; if (string.IsNullOrEmpty(relatePath) || relatePath.LastIndexOf("/") == 0) { relatePath = ""; } else { relatePath = relatePath.Substring(0, relatePath.LastIndexOf("/")); } this.RelatePath = relatePath; } #endregion #region 私有方法 /// <summary> /// 调用Ftp,将命令发往Ftp并返回信息 /// </summary> /// <param name="method">要发往Ftp的命令</param> /// <returns></returns> private FtpWebResponse callFtp(string method) { string uri = string.Format("ftp://{0}:{1}{2}", this.IpAddr, this.Port, this.RelatePath); FtpWebRequest request; request = (FtpWebRequest)FtpWebRequest.Create(uri); request.UseBinary = true; request.UsePassive = true; request.Credentials = new NetworkCredential(UserName, Password); request.KeepAlive = false; request.Method = method; FtpWebResponse response = (FtpWebResponse)request.GetResponse(); return response; } /// <summary> /// 按行读取 /// </summary> /// <param name="response"></param> /// <param name="statusCode"></param> /// <param name="isOk"></param> /// <returns></returns> private string[] ReadByLine(FtpWebResponse response, FtpStatusCode statusCode, out bool isOk) { List<string> lstAccpet = new List<string>(); int i = 0; while (true) { if (response.StatusCode == statusCode) { using (StreamReader sr = new StreamReader(response.GetResponseStream())) { string line = sr.ReadLine(); while (!string.IsNullOrEmpty(line)) { lstAccpet.Add(line); line = sr.ReadLine(); } } isOk = true; break; } i++; if (i > 10) { isOk = false; break; } Thread.Sleep(200); } response.Close(); return lstAccpet.ToArray(); } private void ReadByBytes(string filePath, FtpWebResponse response, FtpStatusCode statusCode, out bool isOk) { isOk = false; int i = 0; while (true) { if (response.StatusCode == statusCode) { long length = response.ContentLength; int bufferSize = 2048; int readCount; byte[] buffer = new byte[bufferSize]; using (FileStream outputStream = new FileStream(filePath, FileMode.Create)) { using (Stream ftpStream = response.GetResponseStream()) { readCount = ftpStream.Read(buffer, 0, bufferSize); while (readCount > 0) { outputStream.Write(buffer, 0, readCount); readCount = ftpStream.Read(buffer, 0, bufferSize); } } } break; } i++; if (i > 10) { isOk = false; break; } Thread.Sleep(200); } response.Close(); } #endregion } /// <summary> /// Ftp内容类型枚举 /// </summary> public enum FtpContentType { undefined = 0, file = 1, folder = 2 } }
然后按钮与Ftp服务器建立连接的点击事件
private void button_connnect_ftpserver_Click(object sender, EventArgs e) { try { checkNull(); if (isRight) { ftpHelper = new FtpHelper(ipAddr, port, userName, password); string[] arrAccept = ftpHelper.ListDirectory(out isOk);//调用Ftp目录显示功能 if (isOk) { MessageBox.Show("登录成功"); } } } catch (Exception ex) { MessageBox.Show("登录失败:ex="+ex.Message); } }
这里调用了非空判断的校验方法checkNull
private void checkNull() { isRight = false; //非空校验 ipAddr = this.textBox_addr.Text.Trim(); port = this.textBox_port.Text.Trim(); userName = this.textBox_name.Text.Trim(); password = this.textBox_pass.Text.Trim(); if (String.IsNullOrEmpty(ipAddr)) { MessageBox.Show("地址不能为空"); } else if (String.IsNullOrEmpty(port)) { MessageBox.Show("端口不能为空"); } else if (String.IsNullOrEmpty(userName)) { MessageBox.Show("用户名不能为空"); } else if (String.IsNullOrEmpty(password)) { MessageBox.Show("密码不能为空"); } else { isRight = true; } }
然后判断是否建立连接成功是通过发送列出所有文件的指令的响应来判断是否建立连接成功。
按钮列出所有文件的点击事件
private void button_listDirectory_Click(object sender, EventArgs e) { checkNull(); if (isRight) { ftpHelper = new FtpHelper(ipAddr, port, userName, password); string[] arrAccept = ftpHelper.ListDirectory(out isOk);//调用Ftp目录显示功能 if (isOk) { this.textBox_log.Clear(); foreach (string accept in arrAccept) { string name = accept.Substring(39); this.textBox_log.AppendText(name); this.textBox_log.AppendText("\r\n"); } } else { this.textBox_log.AppendText("链接失败,或者没有数据"); this.textBox_log.AppendText("\r\n"); } } }
7、上传功能实现
选择上传的文件按钮点击事件
private void button_select_upload_file_Click(object sender, EventArgs e) { OpenFileDialog fileDialog = new OpenFileDialog(); fileDialog.Multiselect = true; fileDialog.Title = "请选择文件"; if (fileDialog.ShowDialog() == DialogResult.OK) { String localFilePath = fileDialog.FileName;//返回文件的完整路径 this.textBox_upload_path.Text = localFilePath; } }
上传文件按钮点击事件
private void button_upload_Click(object sender, EventArgs e) { String uploadPath = this.textBox_upload_path.Text; if (String.IsNullOrEmpty(uploadPath)) { MessageBox.Show("上传文件路径为空"); } else if (!File.Exists(uploadPath)) { MessageBox.Show("文件路径不存在"); } else { string filename = Path.GetFileName(uploadPath); ftpHelper.UpLoad(uploadPath, out isOk, filename); if (isOk) { MessageBox.Show("上传文件成功"); } else { MessageBox.Show("上传文件失败"); } } }
上传文件效果
8、扫描文件并实现单次上传和删除文件
选择扫描文件路径按钮点击事件
private void select_scan_path_Click(object sender, EventArgs e) { FolderBrowserDialog path = new FolderBrowserDialog(); path.ShowDialog(); this.textBox_selected_scan_path.Text = path.SelectedPath; }
扫描文件按钮点击事件
private void button_scan_file_Click(object sender, EventArgs e) { scanedFileList.Clear(); string scanDirectoryPath = this.textBox_selected_scan_path.Text; if (String.IsNullOrEmpty(scanDirectoryPath)) { MessageBox.Show("扫描文件路径不能为空"); } else { //指定的文件夹目录 DirectoryInfo dir = new DirectoryInfo(scanDirectoryPath); if (dir.Exists == false) { MessageBox.Show("路径不存在!请重新输入"); } else { this.textBox_scan_file_list.Clear(); //检索表示当前目录的文件和子目录 FileSystemInfo[] fsinfos = dir.GetFiles(); if (fsinfos.Length == 0) { this.textBox_scan_file_list.AppendText("未扫描到文件"); this.textBox_scan_file_list.AppendText("\r\n"); } else { //遍历检索的文件和子目录 foreach (FileSystemInfo fsinfo in fsinfos) { scanedFileList.Add(fsinfo.FullName); this.textBox_scan_file_list.AppendText(fsinfo.FullName); this.textBox_scan_file_list.AppendText("\r\n"); } } } } }
单次上传扫描的所有文件按钮点击事件
private void button_upload_scaned_file_Click(object sender, EventArgs e) { if (scanedFileList == null || scanedFileList.Count == 0) { MessageBox.Show("没有扫描到文件"); } else { //this.textBox_log.Clear(); for (int index = 0;index<scanedFileList.Count;index++) { //执行上传操作 String uploadPath = scanedFileList[index]; if (!File.Exists(uploadPath)) { this.textBox_log.AppendText(uploadPath + "路径不存在"); this.textBox_log.AppendText("\r\n"); } else { string filename = Path.GetFileName(uploadPath); ftpHelper.UpLoad(uploadPath, out isOk, filename); if (isOk) { this.textBox_log.AppendText(scanedFileList[index] + "上传成功"); this.textBox_log.AppendText("\r\n"); if (File.Exists(uploadPath)) { File.Delete(uploadPath); this.textBox_log.AppendText(scanedFileList[index] + "删除成功"); this.textBox_log.AppendText("\r\n"); } else { this.textBox_log.AppendText(scanedFileList[index] + "删除失败"); this.textBox_log.AppendText("\r\n"); } } else { this.textBox_log.AppendText(scanedFileList[index] + "上传失败"); this.textBox_log.AppendText("\r\n"); } } } } }
实现效果
9、定时扫描实现
声明一个全局定时器变量
//定时器 System.Windows.Forms.Timer _timer = new System.Windows.Forms.Timer();
定时器启动按钮点击事件
private void button_timer_start_Click(object sender, EventArgs e) { decimal interval = this.numericUpDown_interval.Value * 1000; _timer.Interval = (int)interval; _timer.Tick += _timer_Tick; _timer.Start(); }
定时器执行的具体事件实现
private void _timer_Tick(object sender, EventArgs e) { scanedFileList.Clear(); string scanDirectoryPath = this.textBox_selected_scan_path.Text; if (String.IsNullOrEmpty(scanDirectoryPath)) { MessageBox.Show("扫描文件路径不能为空"); } else { //指定的文件夹目录 DirectoryInfo dir = new DirectoryInfo(scanDirectoryPath); if (dir.Exists == false) { MessageBox.Show("路径不存在!请重新输入"); } else { this.textBox_scan_file_list.Clear(); //检索表示当前目录的文件和子目录 FileSystemInfo[] fsinfos = dir.GetFiles(); if (fsinfos.Length == 0) { this.textBox_scan_file_list.AppendText(DateTime.Now.ToString()+"未扫描到文件"); this.textBox_scan_file_list.AppendText("\r\n"); } else { //遍历检索的文件和子目录 foreach (FileSystemInfo fsinfo in fsinfos) { scanedFileList.Add(fsinfo.FullName); this.textBox_scan_file_list.AppendText(fsinfo.FullName); this.textBox_scan_file_list.AppendText("\r\n"); } } } } //执行删除操作 if (scanedFileList == null || scanedFileList.Count == 0) { this.textBox_log.AppendText(DateTime.Now.ToString()+"没有扫描到文件"); this.textBox_log.AppendText("\r\n"); } else { //this.textBox_log.Clear(); for (int index = 0; index < scanedFileList.Count; index++) { //执行上传操作 String uploadPath = scanedFileList[index]; if (!File.Exists(uploadPath)) { this.textBox_log.AppendText(DateTime.Now.ToString()+uploadPath + "路径不存在"); this.textBox_log.AppendText("\r\n"); } else { string filename = Path.GetFileName(uploadPath); ftpHelper.UpLoad(uploadPath, out isOk, filename); if (isOk) { this.textBox_log.AppendText(DateTime.Now.ToString()+scanedFileList[index] + "上传成功"); this.textBox_log.AppendText("\r\n"); if (File.Exists(uploadPath)) { File.Delete(uploadPath); this.textBox_log.AppendText(DateTime.Now.ToString()+scanedFileList[index] + "删除成功"); this.textBox_log.AppendText("\r\n"); } else { this.textBox_log.AppendText(DateTime.Now.ToString()+scanedFileList[index] + "删除失败"); this.textBox_log.AppendText("\r\n"); } } else { this.textBox_log.AppendText(DateTime.Now.ToString()+scanedFileList[index] + "上传失败"); this.textBox_log.AppendText("\r\n"); } } } } }
定时器停止按钮点击事件
private void button_timer_stop_Click(object sender, EventArgs e) { DialogResult AF = MessageBox.Show("您确定停止计时器吗?", "确认框", MessageBoxButtons.OKCancel, MessageBoxIcon.Question); if (AF == DialogResult.OK) { _timer.Stop(); } else { //用户点击取消或者关闭对话框后执行的代码 } }
10、完整示例代码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace UploadFtpServerSchedule { public partial class Form1 : Form { private FtpHelper ftpHelper; //是否建立连接 bool isOk = false; bool isRight = false; string ipAddr = String.Empty; string port = String.Empty; string userName = String.Empty; string password = String.Empty; //存储扫描的所有文件路径 List<String> scanedFileList = new List<string>(); //定时器 System.Windows.Forms.Timer _timer = new System.Windows.Forms.Timer(); public Form1() { InitializeComponent(); } //选择扫描文件路径 private void select_scan_path_Click(object sender, EventArgs e) { FolderBrowserDialog path = new FolderBrowserDialog(); path.ShowDialog(); this.textBox_selected_scan_path.Text = path.SelectedPath; } //ftp建立连接 private void button_connnect_ftpserver_Click(object sender, EventArgs e) { try { checkNull(); if (isRight) { ftpHelper = new FtpHelper(ipAddr, port, userName, password); string[] arrAccept = ftpHelper.ListDirectory(out isOk);//调用Ftp目录显示功能 if (isOk) { MessageBox.Show("登录成功"); } } } catch (Exception ex) { MessageBox.Show("登录失败:ex="+ex.Message); } } private void checkNull() { isRight = false; //非空校验 ipAddr = this.textBox_addr.Text.Trim(); port = this.textBox_port.Text.Trim(); userName = this.textBox_name.Text.Trim(); password = this.textBox_pass.Text.Trim(); if (String.IsNullOrEmpty(ipAddr)) { MessageBox.Show("地址不能为空"); } else if (String.IsNullOrEmpty(port)) { MessageBox.Show("端口不能为空"); } else if (String.IsNullOrEmpty(userName)) { MessageBox.Show("用户名不能为空"); } else if (String.IsNullOrEmpty(password)) { MessageBox.Show("密码不能为空"); } else { isRight = true; } } //列出所有文件 private void button_listDirectory_Click(object sender, EventArgs e) { checkNull(); if (isRight) { ftpHelper = new FtpHelper(ipAddr, port, userName, password); string[] arrAccept = ftpHelper.ListDirectory(out isOk);//调用Ftp目录显示功能 if (isOk) { this.textBox_log.Clear(); foreach (string accept in arrAccept) { string name = accept.Substring(39); this.textBox_log.AppendText(name); this.textBox_log.AppendText("\r\n"); } } else { this.textBox_log.AppendText("链接失败,或者没有数据"); this.textBox_log.AppendText("\r\n"); } } } //选择要上传的文件 private void button_select_upload_file_Click(object sender, EventArgs e) { OpenFileDialog fileDialog = new OpenFileDialog(); fileDialog.Multiselect = true; fileDialog.Title = "请选择文件"; if (fileDialog.ShowDialog() == DialogResult.OK) { String localFilePath = fileDialog.FileName;//返回文件的完整路径 this.textBox_upload_path.Text = localFilePath; } } //上传文件 private void button_upload_Click(object sender, EventArgs e) { String uploadPath = this.textBox_upload_path.Text; if (String.IsNullOrEmpty(uploadPath)) { MessageBox.Show("上传文件路径为空"); } else if (!File.Exists(uploadPath)) { MessageBox.Show("文件路径不存在"); } else { string filename = Path.GetFileName(uploadPath); ftpHelper.UpLoad(uploadPath, out isOk, filename); if (isOk) { MessageBox.Show("上传文件成功"); } else { MessageBox.Show("上传文件失败"); } } } //扫描文件 private void button_scan_file_Click(object sender, EventArgs e) { scanedFileList.Clear(); string scanDirectoryPath = this.textBox_selected_scan_path.Text; if (String.IsNullOrEmpty(scanDirectoryPath)) { MessageBox.Show("扫描文件路径不能为空"); } else { //指定的文件夹目录 DirectoryInfo dir = new DirectoryInfo(scanDirectoryPath); if (dir.Exists == false) { MessageBox.Show("路径不存在!请重新输入"); } else { this.textBox_scan_file_list.Clear(); //检索表示当前目录的文件和子目录 FileSystemInfo[] fsinfos = dir.GetFiles(); if (fsinfos.Length == 0) { this.textBox_scan_file_list.AppendText("未扫描到文件"); this.textBox_scan_file_list.AppendText("\r\n"); } else { //遍历检索的文件和子目录 foreach (FileSystemInfo fsinfo in fsinfos) { scanedFileList.Add(fsinfo.FullName); this.textBox_scan_file_list.AppendText(fsinfo.FullName); this.textBox_scan_file_list.AppendText("\r\n"); } } } } } //单次上传扫描的所有文件 private void button_upload_scaned_file_Click(object sender, EventArgs e) { if (scanedFileList == null || scanedFileList.Count == 0) { MessageBox.Show("没有扫描到文件"); } else { //this.textBox_log.Clear(); for (int index = 0;index<scanedFileList.Count;index++) { //执行上传操作 String uploadPath = scanedFileList[index]; if (!File.Exists(uploadPath)) { this.textBox_log.AppendText(uploadPath + "路径不存在"); this.textBox_log.AppendText("\r\n"); } else { string filename = Path.GetFileName(uploadPath); ftpHelper.UpLoad(uploadPath, out isOk, filename); if (isOk) { this.textBox_log.AppendText(scanedFileList[index] + "上传成功"); this.textBox_log.AppendText("\r\n"); if (File.Exists(uploadPath)) { File.Delete(uploadPath); this.textBox_log.AppendText(scanedFileList[index] + "删除成功"); this.textBox_log.AppendText("\r\n"); } else { this.textBox_log.AppendText(scanedFileList[index] + "删除失败"); this.textBox_log.AppendText("\r\n"); } } else { this.textBox_log.AppendText(scanedFileList[index] + "上传失败"); this.textBox_log.AppendText("\r\n"); } } } } } private void button_timer_start_Click(object sender, EventArgs e) { decimal interval = this.numericUpDown_interval.Value * 1000; _timer.Interval = (int)interval; _timer.Tick += _timer_Tick; _timer.Start(); } private void _timer_Tick(object sender, EventArgs e) { scanedFileList.Clear(); string scanDirectoryPath = this.textBox_selected_scan_path.Text; if (String.IsNullOrEmpty(scanDirectoryPath)) { MessageBox.Show("扫描文件路径不能为空"); } else { //指定的文件夹目录 DirectoryInfo dir = new DirectoryInfo(scanDirectoryPath); if (dir.Exists == false) { MessageBox.Show("路径不存在!请重新输入"); } else { this.textBox_scan_file_list.Clear(); //检索表示当前目录的文件和子目录 FileSystemInfo[] fsinfos = dir.GetFiles(); if (fsinfos.Length == 0) { this.textBox_scan_file_list.AppendText(DateTime.Now.ToString()+"未扫描到文件"); this.textBox_scan_file_list.AppendText("\r\n"); } else { //遍历检索的文件和子目录 foreach (FileSystemInfo fsinfo in fsinfos) { scanedFileList.Add(fsinfo.FullName); this.textBox_scan_file_list.AppendText(fsinfo.FullName); this.textBox_scan_file_list.AppendText("\r\n"); } } } } //执行删除操作 if (scanedFileList == null || scanedFileList.Count == 0) { this.textBox_log.AppendText(DateTime.Now.ToString()+"没有扫描到文件"); this.textBox_log.AppendText("\r\n"); } else { //this.textBox_log.Clear(); for (int index = 0; index < scanedFileList.Count; index++) { //执行上传操作 String uploadPath = scanedFileList[index]; if (!File.Exists(uploadPath)) { this.textBox_log.AppendText(DateTime.Now.ToString()+uploadPath + "路径不存在"); this.textBox_log.AppendText("\r\n"); } else { string filename = Path.GetFileName(uploadPath); ftpHelper.UpLoad(uploadPath, out isOk, filename); if (isOk) { this.textBox_log.AppendText(DateTime.Now.ToString()+scanedFileList[index] + "上传成功"); this.textBox_log.AppendText("\r\n"); if (File.Exists(uploadPath)) { File.Delete(uploadPath); this.textBox_log.AppendText(DateTime.Now.ToString()+scanedFileList[index] + "删除成功"); this.textBox_log.AppendText("\r\n"); } else { this.textBox_log.AppendText(DateTime.Now.ToString()+scanedFileList[index] + "删除失败"); this.textBox_log.AppendText("\r\n"); } } else { this.textBox_log.AppendText(DateTime.Now.ToString()+scanedFileList[index] + "上传失败"); this.textBox_log.AppendText("\r\n"); } } } } } private void button_timer_stop_Click(object sender, EventArgs e) { DialogResult AF = MessageBox.Show("您确定停止计时器吗?", "确认框", MessageBoxButtons.OKCancel, MessageBoxIcon.Question); if (AF == DialogResult.OK) { _timer.Stop(); } else { //用户点击取消或者关闭对话框后执行的代码 } } } }