Система фтп поиска
От: shinji  
Дата: 02.02.06 05:50
Оценка: 2 (1)
Ребята я тут сделал свой фтп индексатор...
Он просто проходиться по всем фтп и всё, что там есть записывает в бд.
Проблема в следующем... странно он както работает то заходит на фтп то не не заходит.
Хотя во втором случае я пробую зайти на фтп фаром и всё заходит спокойно. И еще иногда зависает при записи в бд... :/ тоже не пойму почему... (хотя записей иногда больше миллиона) . Может вы какието советы по отпимизации кода посоветуете или я тут гдето накосячил :/.

Для работы с бд использую бибилотечку MySql Client для .NET скачать можно с сайта www.mysql.com и добавить в референсы.
Структура бд:

Таблица ftps_hosts:
id — INTEGER — автоинкремент
hostname — VARCHAR(255)
online — TINYINT(1)
lastindex — VARCHAR(255)

Таблица ftps_info:
hostid — INTEGER
filename — TEXT
fullpath — TEXT
directory — TINYINT(1)
ext — TEXT
size — BIGINT(20)
fdate — VARCHAR(50)

Если есть у кого время можете посмотреть, что я не так делаю... (покопайтесь в моих сорсах)

Бибилиотечка для работы с фтп
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace Core.FtpClasses
{
    #region Класс "FtpClient"
    public class FtpClient
    {
        #region ПЕРЕМЕННЫЕ
        private string _HostName;
        private string _Login;
        private string _Password;
        private static string _LastDirectory = string.Empty;
        private static string _CurrentDirectory = "/";
        #endregion

        #region КОНСТРУКТОРЫ
        // Конструктор который получает только хост и устанавливает
        // поле Login="Anonymous" и Password=""
        public FtpClient(string HostName)
        {
            _HostName = HostName;
        }
        // Конструктор в который передаеться HostName, Login, Password
        public FtpClient(string HostName, string Login, string Password)
        {
            _HostName = HostName;
            _Login = Login;
            _Password = Password;
        }
        #endregion

        #region СВОЙСТВА
        // Свойство для получения и установки _HostName
        public string HostName
        {
            set { _HostName = value; }
            get
            {
                if (_HostName.StartsWith("ftp://"))
                    return _HostName;
                else
                    return "ftp://" + _HostName;
            }
        }
        // Свойство для получения и установки _Login
        public string Login
        {
            set { _Login = value; }
            get
            {
                if (_Login == string.Empty)
                    return "Anonymous";
                else
                    return _Login;
            }
        }
        // Свойство для получения и установки _Password
        public string Password
        {
            set { _Password = value; }
            get { return _Password; }
        }
        // Получение текущей директории
        public string CurrentDirectory
        {
            set
            {
                if (value.StartsWith("/"))
                    _CurrentDirectory = value;
                else
                    throw new ApplicationException("Директория должна начинаться с знака /");
            }
            get
            {
                if (_CurrentDirectory.EndsWith("/"))
                    return _CurrentDirectory;
                else
                    return _CurrentDirectory + "/";
            }
        }
        #endregion

        #region ВСПОМОГАТЕЛЬНЫЕ ЗАКРЫТЫЕ ФУНКЦИИ
        // Запрос с учетом авторизации
        private FtpWebRequest GetRequest(string URI)
        {
            // Создаем запрос
            FtpWebRequest result = (FtpWebRequest)FtpWebRequest.Create(URI);
            // Устанавливаем логин и пароль
            result.Credentials = GetCredentials();
            result.KeepAlive = false;
            return result;
        }
        // Получение удостовирения личности для авторизации на фтп
        private ICredentials GetCredentials()
        {
            return new NetworkCredential(Login, Password);
        }
        // Получение полного пути
        private string GetFullPath(string file)
        {
            if (file.Contains("/"))
                return AdjustDir(file);
            else
                return this.CurrentDirectory + file;
        }
        // Исправлять фтп путь так чтобы он всегда начинался с /
        private string AdjustDir(string path)
        {
            if (path.StartsWith("/"))
                return path;
            else
                return "/" + path;
        }
        // Функция возвращает директорию
        private string GetDirectory()
        {
            string URI = HostName + this.CurrentDirectory;
            _LastDirectory = this.CurrentDirectory;
            return URI;
        }
        // Функция возвращает уканную директорию
        private string GetDirectory(string directory)
        {
            if (!directory.StartsWith("/"))
                throw new ApplicationException("Директория должна начинаться с /");
            string URI = HostName + directory;
            _LastDirectory = directory;
            return URI;
        }
        // Представляет поток ответа как строку
        private string GetStringResponse(FtpWebRequest ftp)
        {
            string result = string.Empty;
            FtpWebResponse response = (FtpWebResponse)ftp.GetResponse();
            long size = response.ContentLength;
            System.IO.Stream datastream = response.GetResponseStream();
            StreamReader sr = new StreamReader(datastream, Encoding.Default);
            result = sr.ReadToEnd();
            sr.Close();
            datastream.Close();
            response.Close();
            return result;
        }
        // Возвращает размер фтп запроса
        private long GetSize(FtpWebRequest ftp)
        {
            long size;
            FtpWebResponse response = (FtpWebResponse)ftp.GetResponse();
            size = response.ContentLength;
            response.Close();
            return size;
        }
        #endregion

        #region ФУНКЦИИ ДЛЯ РАБОТЫ С ДИРЕКТОРИЯМИ
        // Возвращает простеший список директорий в указанной директории
        public List<string> ListDirectory(string directory)
        {
            FtpWebRequest ftp = GetRequest(GetDirectory(directory));
            ftp.Method = WebRequestMethods.Ftp.ListDirectory;
            string str = GetStringResponse(ftp);
            str = str.Replace("\r\n", "\r").TrimEnd('\r');
            List<string> result = new List<string>();
            result.AddRange(str.Split('\r'));
            return result;
        }
        // Возвращает простейший список директории в текущей директории
        public List<string> ListDirectory()
        {
            FtpWebRequest ftp = GetRequest(GetDirectory());
            ftp.Method = WebRequestMethods.Ftp.ListDirectory;
            string str = GetStringResponse(ftp);
            str = str.Replace("\r\n", "\r").TrimEnd('\r');
            List<string> result = new List<string>();
            result.AddRange(str.Split('\r'));
            return result;
        }
        // Детальная информаци о директории с указанием директории
        public FtpDirectory ListDirectoryDetail(string directory)
        {
            FtpWebRequest ftp = GetRequest(GetDirectory(directory));
            ftp.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
            string str = GetStringResponse(ftp);
            str = str.Replace("\r\n", "\r").TrimEnd('\r');
            return new FtpDirectory(str, _LastDirectory);
        }
        // Возвращает детальную информацию о текущей директории
        public FtpDirectory ListDirectoryDetail()
        {
            FtpWebRequest ftp = GetRequest(GetDirectory());
            ftp.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
            string str = GetStringResponse(ftp);
            str = str.Replace("\r\n", "\r").TrimEnd('\r');
            return new FtpDirectory(str, _LastDirectory);
        }
        #endregion

        #region ФУНКЦИЯ UPLOAD
        // Проверка на существование фаила
        public bool Upload(string LocalFileName)
        {
            if (!File.Exists(LocalFileName))
                throw new ApplicationException("Фаил \"" + LocalFileName + "\" не найден");
            else
            {
                FileInfo fi = new FileInfo(LocalFileName);
                return Upload(fi, string.Empty);
            }
        }
        // Проверка на существование фаила и передача имени фаила в который будет закачен локальный фаил
        public bool Upload(string LocalFileName, string TargetFileName)
        {
            if (!File.Exists(LocalFileName))
                throw new ApplicationException("Фаил \"" + LocalFileName + "\" не найден");
            else
            {
                FileInfo fi = new FileInfo(LocalFileName);
                return Upload(fi, TargetFileName);
            }
        }
        // Функция получает FileInfo и имя фаила в который надо закачать фаил
        private bool Upload(FileInfo fi, string TargetFileName)
        {
            string Target;

            if (TargetFileName.Trim() == string.Empty)
                Target = CurrentDirectory + fi.Name;
            else if (TargetFileName.Contains("/"))
                Target = AdjustDir(TargetFileName);
            else
                Target = CurrentDirectory + TargetFileName;

            string URI = HostName + Target;
            FtpWebRequest ftp = GetRequest(URI);
            ftp.Method = WebRequestMethods.Ftp.UploadFile;
            ftp.UseBinary = true;
            ftp.ContentLength = fi.Length;

            byte[] buffer = new byte[1024];
            int bytesRead;
            FileStream fs = fi.OpenRead();
            try
            {
                Stream rs = ftp.GetRequestStream();
                while (true)
                {
                    bytesRead = fs.Read(buffer, 0, buffer.Length);
                    if (bytesRead == 0)
                        break;
                    rs.Write(buffer, 0, bytesRead);
                }
                rs.Close();
            }
            catch (Exception ex)
            {
                throw new ApplicationException(ex.Message);
            }
            finally
            {
                fs.Close();
            }
            ftp = null;
            return true;
        }
        #endregion

        #region ФУНКЦИЯ DOWNLOAD
        // Главная функция по закачке фаилов
        private bool Download(string SourceFileName, FileInfo TargetFileInfo, bool PermitOverwrite)
        {
            // 1) Проверяем фаил приемник
            if (TargetFileInfo.Exists && !PermitOverwrite)
            {
                throw new ApplicationException("Такой фаил уже существует");
            }

            // 2) Проверяем фаил источник
            string Target;
            if (SourceFileName.Trim() == string.Empty)
            {
                throw new ApplicationException("Фаил не определен");
            }
            else if (SourceFileName.Contains("/"))
            {
                Target = AdjustDir(SourceFileName);
            }
            else
            {
                Target = CurrentDirectory + SourceFileName;
            }

            string URI = HostName + Target;

            FtpWebRequest ftp = GetRequest(URI);
            ftp.Method = WebRequestMethods.Ftp.DownloadFile;
            ftp.UseBinary = true;

            FtpWebResponse response = (FtpWebResponse)ftp.GetResponse();
            Stream responseStream = response.GetResponseStream();
            FileStream fs = TargetFileInfo.OpenWrite();

            try
            {
                byte[] buffer = new byte[1024];
                int read;

                while (true)
                {
                    read = responseStream.Read(buffer, 0, buffer.Length);
                    if (read == 0)
                        break;
                    fs.Write(buffer, 0, read);
                }
                responseStream.Close();
                fs.Flush();
                fs.Close();
            }
            catch (Exception ex)
            {
                fs.Close();
                TargetFileInfo.Delete();
                throw new ApplicationException(ex.Message);
            }
            responseStream.Close();
            response.Close();
            return true;
        }
        // Открытая функция Download обертка
        public bool Download(string SourceFileName, string LocalFileName, bool PermitOverwrite)
        {
            FileInfo fi = new FileInfo(LocalFileName);
            return this.Download(SourceFileName, fi, PermitOverwrite);
        }
        #endregion

        #region ОСТАЛЬНЫЕ ФУНКЦИИ
        // Удалить фаил
        public bool FtpDelete(string FileName)
        {
            string URI = this.HostName + GetFullPath(FileName);
            FtpWebRequest ftp = GetRequest(URI);
            ftp.Method = WebRequestMethods.Ftp.DeleteFile;
            try
            {
                string str = GetStringResponse(ftp);
            }
            catch
            {
                return false;
            }
            return true;
        }
        // Проверить на существование фаил
        public bool FtpFileExists(string FileName)
        {
            try
            {
                long size = GetFileSize(FileName);
                return true;
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("550"))
                    return false;
                else
                    throw new ApplicationException(ex.Message);
            }
        }
        // Получает размер фаила
        public long GetFileSize(string FileName)
        {
            string path;
            if (FileName.Contains("/"))
                path = AdjustDir(FileName);
            else
                path = this.CurrentDirectory + FileName;

            string URI = this.HostName + path;
            FtpWebRequest ftp = GetRequest(URI);
            ftp.Method = WebRequestMethods.Ftp.GetFileSize;
            string tmp = this.GetStringResponse(ftp);
            return GetSize(ftp);
        }
        // Переименовывает фаил
        public bool FtpRename(string SourceFileName, string NewName)
        {
            string source = GetFullPath(SourceFileName);
            if (!FtpFileExists(source))
                throw new ApplicationException("Фаил \"" + source + "\" не найден");

            string target = GetFullPath(NewName);
            if (target == source)
                throw new ApplicationException("Фаил источник и фаил цели имеют одно и тоже имя");
            else if (FtpFileExists(target))
                throw new ApplicationException("Целевой фаил \"" + target + "\" уже существует");

            string URI = this.HostName + source;
            FtpWebRequest ftp = GetRequest(URI);
            ftp.Method = WebRequestMethods.Ftp.Rename;
            ftp.RenameTo = target;

            try
            {
                string str = GetStringResponse(ftp);
            }
            catch
            {
                return false;
            }
            return true;
        }
        // Создает директорию
        public bool FtpCreateDirectory(string DirPath)
        {
            string URI = this.HostName + AdjustDir(DirPath);
            FtpWebRequest ftp = GetRequest(URI);
            ftp.Method = WebRequestMethods.Ftp.MakeDirectory;
            try
            {
                string str = GetStringResponse(ftp);
            }
            catch
            {
                return false;
            }
            return true;
        }
        // Удаляет директорию
        public bool FtpDeleteDirectory(string DirPath)
        {
            string URI = this.HostName + AdjustDir(DirPath);
            FtpWebRequest ftp = GetRequest(URI);
            ftp.Method = WebRequestMethods.Ftp.RemoveDirectory;
            try
            {
                string str = GetStringResponse(ftp);
            }
            catch
            {
                return false;
            }
            return true;
        }
        #endregion
    }
    #endregion

    #region Класс "FtpFileInfo"
    public class FtpFileInfo
    {
        public enum DirectoryEntryTypes { File, Directory };

        #region КОНСТРУКТОР
        public FtpFileInfo(string line, string path)
        {
            Match m = this.GetMatchingRegex(line);
            if (m == null)
                throw new ApplicationException("Не парсит: " + line);
            else
            {
                _FileName = m.Groups["name"].Value;
                _Path = path;
                _Size = Convert.ToInt64(m.Groups["size"].Value);
                _Permission = m.Groups["permission"].Value;

                string _Dir = m.Groups["dir"].Value;
                if (_Dir != string.Empty && _Dir != "-")
                    _FileType = DirectoryEntryTypes.Directory;
                else
                    _FileType = DirectoryEntryTypes.File;

                try
                {
                    _FileDateTime = DateTime.Parse(m.Groups["timestamp"].Value);
                }
                catch
                {
                    _FileDateTime = DateTime.MinValue;
                }
            }
        }
        #endregion

        #region ПЕРЕМЕННЫЕ
        private string _FileName;
        private string _Path;
        private string _Permission;
        private long _Size;
        private DirectoryEntryTypes _FileType;
        private DateTime _FileDateTime;
        #endregion

        #region СВОЙСТВА
        // Получает "путь + имя фаила"
        public string FullName
        {
            get { return Path + FileName; }
        }
        // Получает имя фаила
        public string FileName
        {
            get { return _FileName; }
        }
        // Получает путь
        public string Path
        {
            get { return _Path; }
        }
        // Получает тип фаила
        public DirectoryEntryTypes FileType
        {
            get { return _FileType; }
        }
        // Получает размер фаила
        public long Size
        {
            get { return _Size; }
        }
        // Получает дату
        public DateTime FileDateTime
        {
            get { return _FileDateTime; }
        }
        // Получает уровень доступа
        public string Permission
        {
            get { return _Permission; }
        }
        // Получает расширение фаила
        public string Extension
        {
            get
            {
                int i = this._FileName.LastIndexOf(".");
                if (i >= 0 && i < (this.FileName.Length - 1))
                    return this.FileName.Substring(i + 1);
                else
                    return string.Empty;
            }
        }
        // Получает только имя
        public string NameOnly
        {
            get
            {
                int i = this.FileName.LastIndexOf(".");
                if (i > 0)
                    return this.FileName.Substring(0, i);
                else
                    return this.FileName;
            }
        }
        #endregion

        #region РЕГУЛЯРНЫЕ ВЫРАЖЕНИЯ ДЛЯ ПАРСИНГА
        // Массив с регулярными выражениями
        private string[] RegExprArr = 
            {
                @"(?<dir>[\-d])(?<permission>([\-r][\-w][\-xs]){3})\s+\d+\s+\w+\s+\w+\s+(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{4})\s+(?<name>.+)",
                @"(?<dir>[\-d])(?<permission>([\-r][\-w][\-xs]){3})\s+\d+\s+\d+\s+(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{4})\s+(?<name>.+)",
                @"(?<dir>[\-d])(?<permission>([\-r][\-w][\-xs]){3})\s+\d+\s+\d+\s+(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{1,2}:\d{2})\s+(?<name>.+)",
                @"(?<dir>[\-d])(?<permission>([\-r][\-w][\-xs]){3})\s+\d+\s+\w+\s+\w+\s+(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{1,2}:\d{2})\s+(?<name>.+)",
                @"(?<dir>[\-d])(?<permission>([\-r][\-w][\-xs]){3})(\s+)(?<size>(\d+))(\s+)(?<ctbit>(\w+\s\w+))(\s+)(?<size2>(\d+))\s+(?<timestamp>\w+\s+\d+\s+\d{2}:\d{2})\s+(?<name>.+)",
                @"(?<timestamp>\d{2}\-\d{2}\-\d{2}\s+\d{2}:\d{2}[Aa|Pp][mM])\s+(?<dir>\<\w+\>){0,1}(?<size>\d+){0,1}\s+(?<name>.+)"
            };

        // Функция сравнивающая полученную строку с регулярным выражением
        private Match GetMatchingRegex(string Line)
        {
            Regex r;
            Match m;

            for (int i = 0; i < RegExprArr.Length - 1; i++)
            {
                r = new Regex(RegExprArr[i]);
                m = r.Match(Line);
                if (m.Success)
                    return m;
            }
            return null;
        }
        #endregion
    }
    #endregion

    #region Класс "FtpDirectory"
    public class FtpDirectory : List<FtpFileInfo>
    {
        #region КОНСТРУКТОРЫ
        // Пустой конуструктор
        public FtpDirectory()
        {
        }
        // Конструктор с параметрами
        public FtpDirectory(string dir, string path)
        {
            foreach (string line in dir.Replace("\n", string.Empty).Split('\r'))
                if (line != string.Empty)
                    this.Add(new FtpFileInfo(line, path));
        }
        #endregion

        #region ФУНКЦИИ
        // Функция возвращающая фаилы или директории
        private FtpDirectory GetFileOrDir(FtpFileInfo.DirectoryEntryTypes type)
        {
            FtpDirectory result = new FtpDirectory();
            foreach (FtpFileInfo fi in this)
                if (fi.FileType == type)
                    result.Add(fi);
            return result;
        }
        // Функция возвращающая фаилы или директори по разширению
        private FtpDirectory GetFileOrDir(FtpFileInfo.DirectoryEntryTypes type, string ext)
        {
            FtpDirectory result = new FtpDirectory();
            foreach (FtpFileInfo fi in this)
                if (fi.FileType == type && fi.Extension == ext)
                    result.Add(fi);
            return result;
        }
        // Функция возвращающая директории
        public FtpDirectory GetDirectories()
        {
            return this.GetFileOrDir(FtpFileInfo.DirectoryEntryTypes.Directory);
        }
        // Функция возвращающая только фаилы
        public FtpDirectory GetFiles()
        {
            return this.GetFileOrDir(FtpFileInfo.DirectoryEntryTypes.File);
        }
        // Функция возвращающая фаилы по разширению
        public FtpDirectory GetFiles(string ext)
        {
            return this.GetFileOrDir(FtpFileInfo.DirectoryEntryTypes.File, ext);
        }
        // Функция возвращающая переменную типа bool если фаил существует
        public bool FileExists(string filename)
        {
            foreach (FtpFileInfo ftpfile in this)
                if (ftpfile.FileName == filename)
                    return true;
            return false;
        }
        // Получает родительскую директорию
        public string GetParentDirectory(string dir)
        {
            string tmp = dir.TrimEnd('/');
            int i = tmp.LastIndexOf("/");
            if (i > 0)
                return tmp.Substring(0, i - 1);
            else
                throw new ApplicationException("Нету родительской директории");

        }
        #endregion
    }
    #endregion
}


Код самого фтп поисковика
using System;
using System.Net;
using System.Web;
using System.Data;
using System.Collections.Generic;
using MySql.Data.MySqlClient;
using Core.FtpClasses;

namespace Core.Spyder
{
    class SpyderSqlProvider
    {
        #region ПЕРЕМЕННЫЕ
        private MySqlConnection MySqlCon;
        private MySqlDataAdapter MySqlDA;
        private MySqlCommand MySqlCmd;
        private string ConStr;
        #endregion

        #region PRIVATE ФУНКЦИИ
        private string SqlPharse(string str)
        {
            str = str.Replace("\\", "\\\\");
            str = str.Replace("\'", "\\\'");
            return str;
        }
        private void ExecuteNonQuery(string sqlquery)
        {
            MySqlCon = new MySqlConnection(ConStr);
            MySqlCmd = new MySqlCommand(sqlquery, MySqlCon);

            MySqlCon.Open();
            MySqlCmd.ExecuteNonQuery();
            MySqlCon.Close();

            MySqlCmd.Dispose();
            MySqlCon.Dispose();
        }
        private DataTable GetDataTable(string sqlquery)
        {
            MySqlCon = new MySqlConnection(ConStr);
            MySqlDA = new MySqlDataAdapter(sqlquery, MySqlCon);
            DataTable Result = new DataTable();

            MySqlDA.Fill(Result);

            MySqlCon.Dispose();
            MySqlDA.Dispose();

            return Result;
        }
        private object ExecuteScalar(string sqlquery)
        {
            MySqlCon = new MySqlConnection(ConStr);
            MySqlCmd = new MySqlCommand(sqlquery, MySqlCon);

            MySqlCon.Open();
            object result = MySqlCmd.ExecuteScalar();
            MySqlCon.Close();

            MySqlCmd.Dispose();
            MySqlCon.Dispose();
            
            return result;
        }
        #endregion

        #region СВОЙСТВА
        public string ConnectionString
        {
            set { ConStr = value; }
            get { return ConStr; }
        }
        #endregion

        #region КОНСТРУКТОРЫ
        public SpyderSqlProvider(string ConnectionString)
        {
            ConStr = ConnectionString;
        }
        public SpyderSqlProvider()
        {
            ConStr = "server=localhost;user id=****; password=****; database=core_portal; pooling=true;";
        }
        #endregion

        #region ОТКРЫТЫЕ ФУНКЦИИ ДЛЯ РАБОТЫ С ТАБЛИЦЕЙ "ftps_hosts"
        public List<string> GetHostsList()
        {
            string sqlquery = "SELECT hostname FROM ftps_hosts ORDER BY hostname ASC;";
            DataTable dt = GetDataTable(sqlquery);
            List<string> HostsList = new List<string>();
            for (int i = 0; i < dt.Rows.Count; i++)
                HostsList.Add(dt.Rows[i]["hostname"].ToString().Trim());
            dt.Dispose();
            return HostsList;
        }
        public string GetHostId(string HostName)
        {
            string sqlquery = "SELECT id FROM ftps_hosts WHERE hostname='" + HostName + "';";
            return ExecuteScalar(sqlquery).ToString();
        }
        #endregion

        #region ОТКРЫТЫЕ ФУНКЦИИ ДЛЯ РАБОТЫ С ТАБЛИЦЕЙ "ftps_info"
        public void DeleteFtpInfo(string hostid)
        {
            string sqlquery = "DELETE FROM ftps_info WHERE hostid='" + hostid + "';";
            ExecuteNonQuery(sqlquery);
        }
        public void WriteFtpInfo(string hostid, FtpDirectory ftpdir)
        {
            string sqlquery;
            MySqlCon = new MySqlConnection(ConStr);
            MySqlCmd = new MySqlCommand();
            MySqlCmd.Connection = MySqlCon;
            MySqlCon.Open();
            for (int i = 0; i < ftpdir.Count; i++)
            {
                sqlquery = "INSERT INTO ftps_info (hostid, filename, fullpath, "
                + "directory, ext, size, fdate) VALUES ";
                int isdir;
                if (ftpdir[i].FileType == FtpFileInfo.DirectoryEntryTypes.Directory)
                    isdir = 1;
                else
                    isdir = 0;

                sqlquery += "('" + hostid + "', '"
                + SqlPharse(ftpdir[i].FileName) + "', '"
                + SqlPharse(ftpdir[i].FullName) + "', '"
                + isdir.ToString() + "', '"
                + SqlPharse(ftpdir[i].Extension) + "', '"
                + ftpdir[i].Size.ToString() + "', '"
                + ftpdir[i].FileDateTime.ToString() + "');";
                MySqlCmd.CommandText = sqlquery;
                MySqlCmd.ExecuteNonQuery();
            }
            MySqlCon.Close();
            MySqlCon.Dispose();
            MySqlCmd.Dispose();
        }
        #endregion

     }

    class Spyder
    {
        #region ПЕРЕМЕННЫЕ        
        private List<string> hostslist;
        private FtpDirectory ftpinfo;
        #endregion

        #region КОНСТРУКТОР
        public Spyder()
        {
            ftpinfo = new FtpDirectory();
            LoadHostsList();
            ClearFtpInfo();
        }
        #endregion

        #region ФУНКЦИИ
        public void LoadHostsList()
        {
            SpyderSqlProvider sql = new SpyderSqlProvider();
            hostslist = sql.GetHostsList();
        }
        public void ClearFtpInfo()
        {
            ftpinfo.Clear();
        }
        private void WriteFtpInfo(int i)
        {
            Console.WriteLine("Запись в БД...");
            SpyderSqlProvider sql = new SpyderSqlProvider();
            string hostid = sql.GetHostId(hostslist[i]);
            sql.DeleteFtpInfo(hostid);
            sql.WriteFtpInfo(hostid, ftpinfo);
            Console.WriteLine("Запись в БД завершена.");
        }
        #endregion

        #region ФУНКЦИИ ДЛЯ СКАНИРОВАНИЯ ФТП
        // Сканирует директорию
        private void ScanSubDirs(FtpClient ftp, string directory)
        {
            
            
            if (directory != "/")
                directory += "/";

            FtpDirectory ftpdir = ftp.ListDirectoryDetail(directory);

            for (int i = 0; i < ftpdir.Count; i++)
            {
                if (ftpdir[i].FileName.Trim() != "." && ftpdir[i].FileName.Trim() != ".."
                    && !ftpdir[i].FileName.Trim().Contains("#"))
                {
                    ftpinfo.Add(ftpdir[i]);
                    Console.WriteLine(ftp.HostName + ftpdir[i].FullName);
                }
            }

            for (int i = 0; i < ftpdir.Count; i++)
            {
                if (ftpdir[i].FileType == FtpFileInfo.DirectoryEntryTypes.Directory
                    && ftpdir[i].FileName.Trim() != "." && ftpdir[i].FileName.Trim() != ".."
                    && !ftpdir[i].FileName.Trim().Contains("#"))
                    ScanSubDirs(ftp, ftpdir[i].FullName);
            }
        }
        // Сканирует фтп сервер
        private void ScanFtp(string hostname)
        {
            FtpClient ftp = new FtpClient(hostname);

            if (!hostname.StartsWith("ftp://"))
                hostname = "ftp://" + hostname;

            Console.Title = "Сканирую: " + hostname;
            Console.WriteLine("Соединение с " + hostname);
            ScanSubDirs(ftp, "/");
        }
        // Функция сканирующая все фтп сервера
        public void ScanAllFtp()
        {
            for (int i = 0; i < hostslist.Count; i++)
            {
                try
                {
                    ScanFtp(hostslist[i]);
                    WriteFtpInfo(i);
                }
                catch
                {
                    if (ftpinfo.Count >= 1)
                    {
                        WriteFtpInfo(i);
                        ClearFtpInfo();
                    }
                    else
                    {
                        ClearFtpInfo();
                    }
                }
            }
        }
        #endregion
    }
}


// Код консольного приложения которое всё это дело запускает
using System;
using System.Threading;
using Core.Spyder;

namespace ConsoleApplication
{
    class SpyderConsole
    {
        static void Main(string[] args)
        {
            Spyder spyder = new Spyder();
            while(true)
            {
                spyder.ScanAllFtp();
                spyder.LoadHostsList();
                Console.WriteLine("Следующее сканирование в "
                    + DateTime.Now.Add(new TimeSpan(3, 0, 0)).ToString() + ".");
                Console.Title = "Режим ожидания...";
                Thread.Sleep(new TimeSpan(3, 0, 0));
            }
        }
    }
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.