using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Net; using System.Text; using System.Text.RegularExpressions; namespace SF { public struct FileStruct { public string Flags; public string Owner; public string Group; public bool IsDirectory; public DateTime CreateTime; public string Name; } public enum FileListStyle { UnixStyle, WindowsStyle, Unknown } // Класс для работы с FTP public class FTP { private string Host; private int Port; private string User; private string Password; private string Error; //************************************************************* //* Function: FTP //* Notes: Конструктор класса //* public FTP (string Host, int Port, string User, string Password) { this.Host = Host; this.Port = Port; this.User = User; this.Password = Password; this.Error = ""; } //*** End of FTP *********** //************************************************************* //* Function: UploadFile //* Notes: Запись файла на FTP //* public bool UploadFile (string PathFTP, string NameFile) { FileInfo InfoFile = new FileInfo(NameFile); FtpWebRequest Request; string UploadUri = ""; this.Error = ""; if (PathFTP == "") UploadUri = "ftp://" + this.Host + ":" + this.Port.ToString() + "/" + InfoFile.Name; else UploadUri = "ftp://" + this.Host + ":" + this.Port.ToString() + "/" + PathFTP + "/" + InfoFile.Name; Request = (FtpWebRequest)FtpWebRequest.Create(UploadUri); Request.Credentials = new NetworkCredential(this.User, this.Password); Request.KeepAlive = false; Request.Method = WebRequestMethods.Ftp.UploadFile; Request.UseBinary = true; Request.ContentLength = InfoFile.Length; int BuffLength = 2048; byte[] Buff = new byte[BuffLength]; int ContentLen; FileStream FS = InfoFile.OpenRead(); try { Stream Strm = Request.GetRequestStream(); ContentLen = FS.Read(Buff, 0, BuffLength); while (ContentLen != 0) { Strm.Write(Buff, 0, ContentLen); ContentLen = FS.Read(Buff, 0, BuffLength); } // закрываем все потоки Strm.Close(); FS.Close(); return true; } catch (Exception e) { this.Error = e.Message; return false; } } //*** End of UploadFile *********** //************************************************************* //* Function: DownloadFile //* Notes: Загружает файл NameFileFTP c сервера FTP и записывает //* загруженный файл, на локальный компьтер с именем NameFileLocal. //* public bool DownloadFile (string NameFileFTP, string NameFileLocal) { FtpWebRequest Request; string DownloadUri = ""; try { FileStream OutputStream = new FileStream(NameFileLocal, FileMode.Create); this.Error = ""; DownloadUri = "ftp://" + this.Host + ":" + this.Port.ToString() + "/" + NameFileFTP; Request = (FtpWebRequest)FtpWebRequest.Create(DownloadUri); Request.Method = WebRequestMethods.Ftp.DownloadFile; Request.UseBinary = true; Request.Credentials = new NetworkCredential(this.User, this.Password); FtpWebResponse Response = (FtpWebResponse)Request.GetResponse(); 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); } // закрываем все потоки FtpStream.Close(); OutputStream.Close(); Response.Close(); return true; } catch (Exception e) { this.Error = e.Message; return false; } } //*** End of DownloadFile *********** //************************************************************* //* Function: ListDirectory //* Notes: Возвращает строковый массив списка файлов и каталогов, //* находящихся в указанном каталоге //* public string[] ListDirectory (string PathFTP, bool Details) { string[] DownloadFiles; StringBuilder Result = new StringBuilder(); FtpWebRequest Request; string UriFTP = ""; try { this.Error = ""; if (PathFTP == "") UriFTP = "ftp://" + this.Host + ":" + this.Port.ToString() + "/"; else UriFTP = "ftp://" + this.Host + ":" + this.Port.ToString() + "/" + PathFTP; Request = (FtpWebRequest)FtpWebRequest.Create(UriFTP); Request.UseBinary = true; Request.Credentials = new NetworkCredential(this.User, this.Password); if (Details) Request.Method = WebRequestMethods.Ftp.ListDirectoryDetails; else Request.Method = WebRequestMethods.Ftp.ListDirectory; WebResponse Response = Request.GetResponse(); StreamReader Reader = new StreamReader(Response.GetResponseStream(), Encoding.GetEncoding(1251)); string Line = Reader.ReadLine(); 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[0]); } } catch (Exception e) { this.Error = e.Message; DownloadFiles = new string[0]; return DownloadFiles; } } //*** End of ListDirectory *********** //************************************************************* //* Function: ListNameFile //* Notes: Возвращает строковый массив списка файлов или каталогов //* находящихся в указанном каталоге //* public string[] ListNameFile (string PathFTP, bool Files) { FtpWebRequest Request; string[] ListFile; string UriFTP = ""; int NumDir = 0; int NumFile = 0; try { this.Error = ""; if (PathFTP == "") UriFTP = "ftp://" + this.Host + ":" + this.Port.ToString() + "/"; else UriFTP = "ftp://" + this.Host + ":" + this.Port.ToString() + "/" + PathFTP; Request = (FtpWebRequest)FtpWebRequest.Create(UriFTP); Request.UseBinary = true; Request.Credentials = new NetworkCredential(this.User, this.Password); Request.Method = WebRequestMethods.Ftp.ListDirectoryDetails; WebResponse Response = Request.GetResponse(); StreamReader Reader = new StreamReader(Response.GetResponseStream(), Encoding.GetEncoding(1251)); string Datastring = Reader.ReadToEnd(); Reader.Close(); Response.Close(); FileStruct[] List = GetList(Datastring); foreach (FileStruct thisstruct in List) { if (thisstruct.IsDirectory) NumDir++; else NumFile++; } if (Files) { ListFile = new string[NumFile]; if (NumFile == 0) return ListFile; } else { ListFile = new string[NumDir]; if (NumDir == 0) return ListFile; } int j = 0; for (int i = 0; i < List.Length; i++) { if (Files && !List[i].IsDirectory) ListFile[j++] = List[i].Name; else if (!Files && List[i].IsDirectory) ListFile[j++] = List[i].Name; } return ListFile; } catch (Exception e) { this.Error = e.Message; return new string[0]; } } //*** End of ListNameFile *********** //************************************************************* //* Function: GetList //* private FileStruct[] GetList (string DataStr) { List ListArray = new List(); string[] DataRec = DataStr.Split('\n'); FileListStyle DirListStyle = GetFileListStyle(DataRec); foreach (string s in DataRec) { if (DirListStyle != FileListStyle.Unknown && s != "") { FileStruct FS = new FileStruct(); FS.Name = ".."; switch (DirListStyle) { case FileListStyle.UnixStyle: FS = ParseFileStructUnixStyle(s); break; case FileListStyle.WindowsStyle: FS = ParseFileStructWindowsStyle(s); break; } if (!(FS.Name == "." || FS.Name == "..")) { ListArray.Add(FS); } } } return ListArray.ToArray(); } //*** End of GetList *********** //************************************************************* //* Function: ParseFileStructUnixStyle //* private FileStruct ParseFileStructUnixStyle (string Record) { // dr-xr-xr-x 1 owner group 0 Nov 25 2002 bussys FileStruct FS = new FileStruct(); string ProcStr = Record.Trim(); if (ProcStr.ToLower() == "total 0") { FS.Name = ""; return FS; } FS.Flags = ProcStr.Substring(0, 9); FS.IsDirectory = (FS.Flags[0] == 'd'); ProcStr = (ProcStr.Substring(11)).Trim(); CutSubstr(ref ProcStr, ' ', 0); FS.Owner = CutSubstr(ref ProcStr, ' ', 0); FS.Group = CutSubstr(ref ProcStr, ' ', 0); CutSubstr(ref ProcStr, ' ', 0); try { FS.CreateTime = DateTime.Parse(CutSubstr(ref ProcStr, ' ', 8)); } catch { FS.CreateTime = DateTime.Now; } if (ProcStr.IndexOf(" ") > 0) FS.Name = "\"" + ProcStr + "\""; else FS.Name = ProcStr; return FS; } //*** End of ParseFileStructUnixStyle *********** //************************************************************* //* Function: ParseFileStructWindowsStyle //* private FileStruct ParseFileStructWindowsStyle (string Record) { // 02-03-04 07:46PM Append FileStruct FS = new FileStruct(); string ProcStr = Record.Trim(); string DateStr = ProcStr.Substring(0, 8); ProcStr = (ProcStr.Substring(8, ProcStr.Length - 8)).Trim(); string TimeStr = ProcStr.Substring(0, 7); ProcStr = (ProcStr.Substring(7, ProcStr.Length - 7)).Trim(); try { FS.CreateTime = DateTime.Parse(DateStr + " " + TimeStr); } catch { FS.CreateTime = DateTime.Now; } if (ProcStr.Substring(0, 5) == "") { FS.IsDirectory = true; ProcStr = (ProcStr.Substring(5, ProcStr.Length - 5)).Trim(); } else { string[] StrS = ProcStr.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // имя файла с пробелами внутри, обрамляем строку двойными кавычками if (StrS.Length > 2) { ProcStr = ""; for (int i = 1; i < StrS.Length; i++) ProcStr = ProcStr + StrS[i] + " "; ProcStr = "\"" + ProcStr.Trim() + "\""; } else ProcStr = StrS[1].Trim(); FS.IsDirectory = false; } FS.Name = ProcStr; return FS; } //*** End of ParseFileStructWindowsStyle *********** //************************************************************* //* Function: GetFileListStyle //* Notes: //* public FileListStyle GetFileListStyle (string[] RecList) { foreach (string s in RecList) { if (s.Length > 10 && Regex.IsMatch(s.Substring(0, 10), "(-|d)(-|r)(-|w)(-|x)(-|r)(-|w)(-|x)(-|r)(-|w)(-|x)")) { return FileListStyle.UnixStyle; } else if (s.Length > 8 && Regex.IsMatch(s.Substring(0, 8), "[0-9][0-9]-[0-9][0-9]-[0-9][0-9]")) { return FileListStyle.WindowsStyle; } } return FileListStyle.Unknown; } //*** End of GetFileListStyle *********** //************************************************************* //* Function: CutSubstr //* Notes: //* private string CutSubstr (ref string s, char c, int startIndex) { int pos1 = s.IndexOf(c, startIndex); string retString = s.Substring(0, pos1); s = (s.Substring(pos1)).Trim(); return retString; } //*** End of CutSubstr *********** // получить сообщение об ошибке public string Err { get { return this.Error; } } } }