using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.IO; using System.Text.RegularExpressions; public class FtpClient { /// <summary> /// FTP请求对象 /// </summary> FtpWebRequest request = null; /// <summary> /// FTP响应对象 /// </summary> FtpWebResponse response = null; /// <summary> /// FTP服务器地址 /// </summary> public string ftpURI { get; private set; } /// <summary> /// FTP服务器IP /// </summary> public string ftpServerIP { get; private set; } /// <summary> /// FTP服务器默认目录 /// </summary> public string ftpRemotePath { get; private set; } /// <summary> /// FTP服务器登录用户名 /// </summary> public string ftpUserID { get; private set; } /// <summary> /// FTP服务器登录密码 /// </summary> public string ftpPassword { get; private set; } /// <summary> /// 初始化 /// </summary> /// <param name="FtpServerIP">FTP连接地址</param> /// <param name="FtpRemotePath">指定FTP连接成功后的当前目录, 如果不指定即默认为根目录</param> /// <param name="FtpUserID">用户名</param> /// <param name="FtpPassword">密码</param> public FtpClient(string ftpServerIP, string ftpRemotePath, string ftpUserID, string ftpPassword) { this.ftpServerIP = ftpServerIP; this.ftpRemotePath = ftpRemotePath; this.ftpUserID = ftpUserID; this.ftpPassword = ftpPassword; this.ftpURI = "ftp://" + ftpServerIP + "/" + ftpRemotePath + "/"; } ~FtpClient() { if (response != null) { response.Close(); response = null; } if (request != null) { request.Abort(); request = null; } } /// <summary> /// 建立FTP链接,返回响应对象 /// </summary> /// <param name="uri">FTP地址</param> /// <param name="ftpMethod">操作命令</param> /// <returns></returns> private FtpWebResponse Open(Uri uri, string ftpMethod) { request = (FtpWebRequest)FtpWebRequest.Create(uri); request.Proxy = null; request.Method = ftpMethod; request.UseBinary = true; request.KeepAlive = false; request.Credentials = new NetworkCredential(this.ftpUserID, this.ftpPassword); return (FtpWebResponse)request.GetResponse(); } /// <summary> /// 建立FTP链接,返回请求对象 /// </summary> /// <param name="uri">FTP地址</param> /// <param name="ftpMethod">操作命令</param> private FtpWebRequest OpenRequest(Uri uri, string ftpMethod) { request = (FtpWebRequest)WebRequest.Create(urih); request.Proxy = null; request.Method = ftpMethod; request.UseBinary = true; request.KeepAlive = false; request.Credentials = new NetworkCredential(this.ftpUserID, this.ftpPassword); return request; } /// <summary> /// 创建目录 /// </summary> /// <param name="remoteDirectoryName">目录名</param> public void CreateDirectory(string remoteDirectoryName) { try { response = Open(new Uri(ftpURI), WebRequestMethods.Ftp.MakeDirectory); } catch { } } /// <summary> /// 更改目录或文件名 /// </summary> /// <param name="currentName">当前名称</param> /// <param name="newName">修改后新名称</param> public void ReName(string currentName, string newName) { request = OpenRequest(new Uri(ftpURI + currentName), WebRequestMethods.Ftp.Rename); request.RenameTo = newName; response = (FtpWebResponse)request.GetResponse(); } /// <summary> /// 切换当前目录 /// </summary> /// <param name="IsRoot">true:绝对路径 false:相对路径</param> public void GotoDirectory(string DirectoryName, bool IsRoot) { if (IsRoot) ftpRemotePath = DirectoryName; else ftpRemotePath += "/" + DirectoryName; ftpURI = "ftp://" + ftpServerIP + "/" + ftpRemotePath + "/"; } /// <summary> /// 删除目录(包括下面所有子目录和子文件) /// </summary> /// <param name="remoteDirectoryName">要删除的带路径目录名:如web/test</param> /* * 例:删除test目录 FTPHelper helper = new FTPHelper("x.x.x.x", "web", "user", "password"); helper.RemoveDirectory("web/test"); */ public void RemoveDirectory(string remoteDirectoryName) { GotoDirectory(remoteDirectoryName, true); var listAll = ListFilesAndDirectories(); foreach (var m in listAll) { if (m.IsDirectory) RemoveDirectory(m.Path); else DeleteFile(m.Name); } GotoDirectory(remoteDirectoryName, true); response = Open(new Uri(ftpURI), WebRequestMethods.Ftp.RemoveDirectory); } /// <summary> /// 文件上传 /// </summary> /// <param name="localFilePath">本地文件路径</param> public bool Upload(string localFilePath,ref string Errmsg) { try { FileInfo fileInf = new FileInfo(localFilePath); request = OpenRequest(new Uri(ftpURI + fileInf.Name), WebRequestMethods.Ftp.UploadFile); request.ContentLength = fileInf.Length; int buffLength = 2048; byte[] buff = new byte[buffLength]; int contentLen; using (var fs = fileInf.OpenRead()) { using (var strm = request.GetRequestStream()) { contentLen = fs.Read(buff, 0, buffLength); while (contentLen != 0) { strm.Write(buff, 0, contentLen); contentLen = fs.Read(buff, 0, buffLength); } } } return true; } catch(Exception ex) { Errmsg = ex.Message; return false; } } /// <summary> /// 删除文件 /// </summary> /// <param name="remoteFileName">要删除的文件名</param> public void DeleteFile(string remoteFileName) { response = Open(new Uri(ftpURI + remoteFileName), WebRequestMethods.Ftp.DeleteFile); } /// <summary> /// 获取当前目录的文件和一级子目录信息 /// </summary> /// <returns></returns> public List<FileStruct> ListFilesAndDirectories() { var fileList = new List<FileStruct>(); response = Open(new Uri(ftpURI), WebRequestMethods.Ftp.ListDirectoryDetails); using (var stream = response.GetResponseStream()) { using (var sr = new StreamReader(stream)) { string line = null; while ((line = sr.ReadLine()) != null) { if (line.Contains(".pdf")) { Regex reg = new Regex(@" d{4} "); var result = reg.Match(line).Groups; if (result.Count > 0) { int index = line.IndexOf(result[0].Value); string filename = line.Substring(index + 5).Trim(); FileStruct model = new FileStruct(); model.Name = filename; fileList.Add(model); } } } } } return fileList; } /// <summary> /// 列出当前目录的所有文件 /// </summary> public List<FileStruct> ListFiles() { var listAll = ListFilesAndDirectories(); var listFile = listAll.Where(m => m.IsDirectory == false).ToList(); return listFile; } /// <summary> /// 列出当前目录的所有一级子目录 /// </summary> public List<FileStruct> ListDirectories() { var listAll = ListFilesAndDirectories(); var listFile = listAll.Where(m => m.IsDirectory == true).ToList(); return listFile; } /// <summary> /// 判断当前目录下指定的子目录或文件是否存在 /// </summary> /// <param name="remoteName">指定的目录或文件名</param> public bool IsExist(string remoteName) { var list = ListFilesAndDirectories(); if (list.Count(m => m.Name == remoteName) > 0) return true; return false; } /// <summary> /// 判断当前目录下指定的一级子目录是否存在 /// </summary> /// <param name="RemoteDirectoryName">指定的目录名</param> public bool IsDirectoryExist(string remoteDirectoryName) { var listDir = ListDirectories(); if (listDir.Count(m => m.Name == remoteDirectoryName) > 0) return true; return false; } /// <summary> /// 判断当前目录下指定的子文件是否存在 /// </summary> /// <param name="RemoteFileName">远程文件名</param> public bool IsFileExist(string remoteFileName) { var listFile = ListFiles(); if (listFile.Count(m => m.Name == remoteFileName) > 0) return true; return false; } /// <summary> /// 下载 /// </summary> /// <param name="saveFilePath">下载后的保存路径</param> /// <param name="downloadFileName">要下载的文件名</param> public bool Download(string saveFilePath, string downloadFileName,ref string Errmsg) { Errmsg = ""; try { string savename = saveFilePath; FileStream outputStream = new FileStream(savename, FileMode.Create); response = Open(new Uri(ftpURI + downloadFileName), WebRequestMethods.Ftp.DownloadFile); using (Stream ftpStream = response.GetResponseStream()) { long cl = response.ContentLength; int bufferSize = 2048; int readCount; byte[] buffer = new byte[bufferSize]; readCount = ftpStream.Read(buffer, 0, bufferSize); while (readCount > 0) { outputStream.Write(buffer, 0, readCount); readCount = ftpStream.Read(buffer, 0, bufferSize); } } outputStream.Close(); if (File.Exists(savename)) { return true; } else { return false; } } catch(Exception ex) { LogHelpers.Info("文件下载失败:"+ downloadFileName); InsertMsg(downloadFileName); Errmsg = ex.Message; return false; } } /// <summary> /// 插入消息到SQLITE /// </summary> /// <param name="tablename"></param> /// <param name="status"></param> /// <param name="msg"></param> public void InsertMsg(string downloadFileName) { string dbmsg = AppDomain.CurrentDomain.BaseDirectory + "Log\GateWay.db"; SqLiteDB mymsg = new SqLiteDB(dbmsg); string sql = "insert into downfail(Pdfname,addtime) values('"+downloadFileName+"','"+DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")+"')"; mymsg.ExecuteSql(sql); } } public class FileStruct { /// <summary> /// 是否为目录 /// </summary> public bool IsDirectory { get; set; } /// <summary> /// 创建时间 /// </summary> public DateTime CreateTime { get; set; } /// <summary> /// 文件或目录名称 /// </summary> public string Name { get; set; } /// <summary> /// 路径 /// </summary> public string Path { get; set; } } public enum LogType { Overall, } public static class LogHelpers { public static string LogPath { get { return AppDomain.CurrentDomain.BaseDirectory + @"log"; } } public enum LogLevel { Info, Error } public static void Info(string message, LogType logType = LogType.Overall) { if (string.IsNullOrEmpty(message)) return; var path = string.Format(@"{0}", logType.ToString()); WriteLog(path, "", message); } public static void Error(string message, LogType logType = LogType.Overall) { if (string.IsNullOrEmpty(message)) return; var path = string.Format(@"{0}", logType.ToString()); WriteLog(path, "Error ", message); } public static void Error(Exception e, LogType logType = LogType.Overall) { if (e == null) return; var path = string.Format(@"{0}", logType.ToString()); WriteLog(path, "Error ", e.Message); } private static void WriteLog(string path, string prefix, string message) { path = LogPath + path; var fileName = string.Format("{0}{1}.log", prefix, DateTime.Now.ToString("yyyyMMdd")); if (!Directory.Exists(path)) Directory.CreateDirectory(path); using (FileStream fs = new FileStream(path + fileName, FileMode.Append, FileAccess.Write, FileShare.Write, 1024, FileOptions.Asynchronous)) { byte[] buffer = System.Text.Encoding.UTF8.GetBytes(DateTime.Now.ToString("HH:mm:ss") + " " + message + " "); IAsyncResult writeResult = fs.BeginWrite(buffer, 0, buffer.Length, (asyncResult) => { var fStream = (FileStream)asyncResult.AsyncState; fStream.EndWrite(asyncResult); }, fs); fs.Close(); } } }
今天在下载,上传文件的时候,发现出错了,报错为:
使用 HTTP 代理时不支持请求的 FTP 命令。
后来设置
request.Proxy = null;
解决问题。