C#使用FTP服务器目录填充TreeView

时间:2013-09-16 14:46:11

标签: c# ftp

我在网上搜索过,对此仍是新手。请耐心等待我。

我想做的是: - 我有一个名为“treeTO”的TreeView。 - 我连接到我的FTP服务器,我想在树视图中填充这里的所有内容(目录,子目录和文件,无论它是什么)。 - 这是我到目前为止的代码:

FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://" + ActiveServer.Server + "/");
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
request.Credentials = new NetworkCredential(ActiveServer.UserName, ActiveServer.Password);
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);

- 这会返回以下文本:Logs,Data和WwwRoot。

我很难将其添加到树视图中,然后遍历文件夹以将所有内容添加到树视图中。

3 个答案:

答案 0 :(得分:3)

所以这是我的工作解决方案!

当然,您必须将“root”的值替换为FTP-Server的rootURL,并在方法GetWebRequest()中将“username”和“password”替换为您的凭证!

您需要此类来保存详细信息

public class FTPListDetail
{
        public bool IsDirectory
        {
            get
            {
                return !string.IsNullOrWhiteSpace(Dir) && Dir.ToLower().Equals("d");
            }
        }
        internal string Dir { get; set; }
        public string Permission { get; set; }
        public string Filecode { get; set; }
        public string Owner { get; set; }
        public string Group { get; set; }
        public string Name { get; set; }
        public string FullPath { get; set; }
}

以下是WinForm-App的代码隐藏

private void button1_Click(object sender, EventArgs e)
{
    var root = "ftp://ftp.yourFTPServer.at";

    treeView1.Nodes.Clear();
    treeView1.Nodes.Add(CreateDirectoryNode(root, "root"));
}

private TreeNode CreateDirectoryNode(string path, string name)
{
    var directoryNode = new TreeNode(name);
    var directoryListing = GetDirectoryListing(path);

    var directories = directoryListing.Where(d => d.IsDirectory);
    var files = directoryListing.Where(d => !d.IsDirectory);

    foreach (var dir in directories)
    {
        directoryNode.Nodes.Add(CreateDirectoryNode(dir.FullPath, dir.Name));
    }
    foreach (var file in files)
    {
            directoryNode.Nodes.Add(new TreeNode(file.Name));
    }
    return directoryNode;
}

public IEnumerable<FTPListDetail> GetDirectoryListing(string rootUri)
{
    var CurrentRemoteDirectory = rootUri;
    var result = new StringBuilder();
    var request = GetWebRequest(WebRequestMethods.Ftp.ListDirectoryDetails, CurrentRemoteDirectory);
    using (var response = request.GetResponse())
    {
        using (var reader = new StreamReader(response.GetResponseStream()))
        {
            string line = reader.ReadLine();
            while (line != null)
            {
                result.Append(line);
                result.Append("\n");
                line = reader.ReadLine();
            }
            if (string.IsNullOrEmpty(result.ToString()))
            {
                return new List<FTPListDetail>();
            }
            result.Remove(result.ToString().LastIndexOf("\n"), 1);
            var results = result.ToString().Split('\n');
            string regex =
                @"^" +               //# Start of line
                @"(?<dir>[\-ld])" +          //# File size          
                @"(?<permission>[\-rwx]{9})" +            //# Whitespace          \n
                @"\s+" +            //# Whitespace          \n
                @"(?<filecode>\d+)" +
                @"\s+" +            //# Whitespace          \n
                @"(?<owner>\w+)" +
                @"\s+" +            //# Whitespace          \n
                @"(?<group>\w+)" +
                @"\s+" +            //# Whitespace          \n
                @"(?<size>\d+)" +
                @"\s+" +            //# Whitespace          \n
                @"(?<month>\w{3})" +          //# Month (3 letters)   \n
                @"\s+" +            //# Whitespace          \n
                @"(?<day>\d{1,2})" +        //# Day (1 or 2 digits) \n
                @"\s+" +            //# Whitespace          \n
                @"(?<timeyear>[\d:]{4,5})" +     //# Time or year        \n
                @"\s+" +            //# Whitespace          \n
                @"(?<filename>(.*))" +            //# Filename            \n
                @"$";                //# End of line

            var myresult = new List<FTPListDetail>();
            foreach (var parsed in results)
            {
                var split = new Regex(regex)
                    .Match(parsed);
                var dir = split.Groups["dir"].ToString();
                var permission = split.Groups["permission"].ToString();
                var filecode = split.Groups["filecode"].ToString();
                var owner = split.Groups["owner"].ToString();
                var group = split.Groups["group"].ToString();
                var filename = split.Groups["filename"].ToString();
                myresult.Add(new FTPListDetail()
                {
                    Dir = dir,
                    Filecode = filecode,
                    Group = group,
                    FullPath = CurrentRemoteDirectory + "/" + filename,
                    Name = filename,
                    Owner = owner,
                    Permission = permission,
                });
            };
            return myresult;
        }
    }
}

private FtpWebRequest GetWebRequest(string method, string uri)
{
    Uri serverUri = new Uri(uri);
    if (serverUri.Scheme != Uri.UriSchemeFtp)
    {
        return null;
    }
    var reqFTP = (FtpWebRequest)FtpWebRequest.Create(serverUri);
    reqFTP.Method = method;
    reqFTP.UseBinary = true;
    reqFTP.Credentials = new NetworkCredential("yourUser", "yourPassword");
    reqFTP.Proxy = null;
    reqFTP.KeepAlive = false;
    reqFTP.UsePassive = false;
    return reqFTP;
}

答案 1 :(得分:1)

有一个原因是,地球上没有FTP客户端抢先填充FTP服务器上的树视图或在树视图中显示文件图标。其中任何一个都会永远消失。

你需要做的是重新思考你是如何做到这一点的。当您第一次连接时,您将只想填充树,直到初始目录,然后是初始目录。您不希望将文件放在树视图中,因为在许多实际情况下,这也会占用太多内存。只需添加文件夹(并为&gt; 99%使用相同的ICON)。

这是您第一次登录时的样子:

/
-home
 -joe
  -public_html
  -docs
  -uploads

请注意,此时'/'和'home'尚未完全读取,我们只是将它们作为占位符插入以供用户单击。之后,您只想添加单击文件夹中的目录,每次用户单击文件夹时都不存在这些目录。

这种策略将使生活变得轻松一百万倍。即使你想尝试那些更复杂的方法来处理这个问题,你也会想要从基础开始。

答案 2 :(得分:0)

我上过这堂课

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;

namespace Backup_service
{
    internal class Ftp_Client
    {
        //поля
        //поле для хранения имени фтп-сервера
        private string _Host;

        //поле для хранения логина
        private string _UserName;

        //поле для хранения пароля
        private string _Password;

        //объект для запроса данных
        private FtpWebRequest ftpRequest;

        //объект для получения данных
        private FtpWebResponse ftpResponse;

        //флаг использования SSL
        private bool _UseSSL = false;

        //фтп-сервер
        public string Host
        {
            get
            {
                return _Host;
            }
            set
            {
                _Host = value;
            }
        }

        //логин
        public string UserName
        {
            get
            {
                return _UserName;
            }
            set
            {
                _UserName = value;
            }
        }

        //пароль
        public string Password
        {
            get
            {
                return _Password;
            }
            set
            {
                _Password = value;
            }
        }

        //Для установки SSL-чтобы данные нельзя было перехватить
        public bool UseSSL
        {
            get
            {
                return _UseSSL;
            }
            set
            {
                _UseSSL = value;
            }
        }

        //Реализеум команду LIST для получения подробного списока файлов на FTP-сервере
        public FileStruct[] ListDirectory(string path)
        {
            if (path == null || path == "")
            {
                path = "/";
            }
            //Создаем объект запроса
            ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + _Host + path);
            //логин и пароль
            ftpRequest.Credentials = new NetworkCredential(_UserName, _Password);
            //команда фтп LIST
            ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;

            ftpRequest.EnableSsl = _UseSSL;
            //Получаем входящий поток
            ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();

            //переменная для хранения всей полученной информации
            string content = "";

            StreamReader sr = new StreamReader(ftpResponse.GetResponseStream(), System.Text.Encoding.ASCII);
            content = sr.ReadToEnd();
            sr.Close();
            ftpResponse.Close();

            DirectoryListParser parser = new DirectoryListParser(content);
            return parser.FullListing;
        }

        //метод протокола FTP RETR для загрузки файла с FTP-сервера
        public void DownloadFile(string path, string currentfileName)
        {
            ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + _Host + path);

            ftpRequest.Credentials = new NetworkCredential(_UserName, _Password);
            //команда фтп RETR
            ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;

            ftpRequest.EnableSsl = _UseSSL;
            //Файлы будут копироваться в кталог программы
            if (!Directory.Exists(currentfileName))
            {
                Directory.CreateDirectory(currentfileName);
            }
            FileStream downloadedFile = new FileStream(currentfileName + @"\" + path.Substring(path.LastIndexOf('/') + 1), FileMode.Create, FileAccess.ReadWrite);

            ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
            //Получаем входящий поток
            Stream responseStream = ftpResponse.GetResponseStream();

            //Буфер для считываемых данных
            byte[] buffer = new byte[1024];
            int size = 0;

            while ((size = responseStream.Read(buffer, 0, 1024)) > 0)
            {
                downloadedFile.Write(buffer, 0, size);
            }
            ftpResponse.Close();
            downloadedFile.Close();
            responseStream.Close();
        }

        //метод протокола FTP STOR для загрузки файла на FTP-сервер
        public void UploadFile(string path, string fileName)
        {
            //для имени файла
            string shortName = fileName.Remove(0, fileName.LastIndexOf("\\") + 1);

            FileStream uploadedFile = new FileStream(fileName, FileMode.Open, FileAccess.Read);

            ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + _Host + path + shortName);
            ftpRequest.Credentials = new NetworkCredential(_UserName, _Password);
            ftpRequest.EnableSsl = _UseSSL;
            ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;

            //Буфер для загружаемых данных
            byte[] file_to_bytes = new byte[uploadedFile.Length];
            //Считываем данные в буфер
            uploadedFile.Read(file_to_bytes, 0, file_to_bytes.Length);

            uploadedFile.Close();

            //Поток для загрузки файла
            Stream writer = ftpRequest.GetRequestStream();

            writer.Write(file_to_bytes, 0, file_to_bytes.Length);
            writer.Close();
        }

        //метод протокола FTP DELE для удаления файла с FTP-сервера
        public void DeleteFile(string path)
        {
            ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + _Host + path);
            ftpRequest.Credentials = new NetworkCredential(_UserName, _Password);
            ftpRequest.EnableSsl = _UseSSL;
            ftpRequest.Method = WebRequestMethods.Ftp.DeleteFile;

            FtpWebResponse ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
            ftpResponse.Close();
        }

        //метод протокола FTP MKD для создания каталога на FTP-сервере
        public void CreateDirectory(string path, string folderName)
        {
            FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + _Host + path + folderName);

            ftpRequest.Credentials = new NetworkCredential(_UserName, _Password);
            ftpRequest.EnableSsl = _UseSSL;
            ftpRequest.Method = WebRequestMethods.Ftp.MakeDirectory;

            FtpWebResponse ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
            ftpResponse.Close();
        }

        //метод протокола FTP RMD для удаления каталога с FTP-сервера
        public void RemoveDirectory(string path)
        {
            string filename = path;
            FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + _Host + path);
            ftpRequest.Credentials = new NetworkCredential(_UserName, _Password);
            ftpRequest.EnableSsl = _UseSSL;
            ftpRequest.Method = WebRequestMethods.Ftp.RemoveDirectory;

            FtpWebResponse ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
            ftpResponse.Close();
        }
    }

    //Для парсинга полученного детального списка каталогов фтп-сервера
    //Структура для хранения детальной информации о файле или каталоге
    public struct FileStruct
    {
        public string Flags;
        public string Owner;
        public bool IsDirectory;
        public string CreateTime;
        public string Name;
    }

    public enum FileListStyle
    {
        UnixStyle,
        WindowsStyle,
        Unknown
    }

    //Класс для парсинга
    public class DirectoryListParser
    {
        private List<FileStruct> _myListArray;

        public FileStruct[] FullListing
        {
            get
            {
                return _myListArray.ToArray();
            }
        }

        public FileStruct[] FileList
        {
            get
            {
                List<FileStruct> _fileList = new List<FileStruct>();
                foreach (FileStruct thisstruct in _myListArray)
                {
                    if (!thisstruct.IsDirectory)
                    {
                        _fileList.Add(thisstruct);
                    }
                }
                return _fileList.ToArray();
            }
        }

        public FileStruct[] DirectoryList
        {
            get
            {
                List<FileStruct> _dirList = new List<FileStruct>();
                foreach (FileStruct thisstruct in _myListArray)
                {
                    if (thisstruct.IsDirectory)
                    {
                        _dirList.Add(thisstruct);
                    }
                }
                return _dirList.ToArray();
            }
        }

        public DirectoryListParser(string responseString)
        {
            _myListArray = GetList(responseString);
        }

        private List<FileStruct> GetList(string datastring)
        {
            List<FileStruct> myListArray = new List<FileStruct>();
            string[] dataRecords = datastring.Split('\n');
            //Получаем стиль записей на сервере
            FileListStyle _directoryListStyle = GuessFileListStyle(dataRecords);
            foreach (string s in dataRecords)
            {
                if (_directoryListStyle != FileListStyle.Unknown && s != "")
                {
                    FileStruct f = new FileStruct();
                    f.Name = "..";
                    switch (_directoryListStyle)
                    {
                        case FileListStyle.UnixStyle:
                            f = ParseFileStructFromUnixStyleRecord(s);
                            break;

                        case FileListStyle.WindowsStyle:
                            f = ParseFileStructFromWindowsStyleRecord(s);
                            break;
                    }
                    if (f.Name != "" && f.Name != "." && f.Name != "..")
                    {
                        myListArray.Add(f);
                    }
                }
            }
            return myListArray;
        }

        //Парсинг, если фтп сервера работает на Windows
        private FileStruct ParseFileStructFromWindowsStyleRecord(string Record)
        {
            //Предположим стиль записи 02-03-04  07:46PM       <DIR>     Append
            FileStruct f = new FileStruct();
            string processstr = Record.Trim();
            //Получаем дату
            string dateStr = processstr.Substring(0, 8);
            processstr = (processstr.Substring(8, processstr.Length - 8)).Trim();
            //Получаем время
            string timeStr = processstr.Substring(0, 7);
            processstr = (processstr.Substring(7, processstr.Length - 7)).Trim();
            f.CreateTime = dateStr + " " + timeStr;
            //Это папка или нет
            if (processstr.Substring(0, 5) == "<DIR>")
            {
                f.IsDirectory = true;
                processstr = (processstr.Substring(5, processstr.Length - 5)).Trim();
            }
            else
            {
                string[] strs = processstr.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                processstr = strs[1];
                f.IsDirectory = false;
            }
            //Остальное содержмое строки представляет имя каталога/файла
            f.Name = processstr;
            return f;
        }

        //Получаем на какой ОС работает фтп-сервер - от этого будет зависеть дальнейший парсинг
        public FileListStyle GuessFileListStyle(string[] recordList)
        {
            foreach (string s in recordList)
            {
                //Если соблюдено условие, то используется стиль Unix
                if (s.Length > 10
                    && Regex.IsMatch(s.Substring(0, 10), "(-|d)((-|r)(-|w)(-|x)){3}"))
                {
                    return FileListStyle.UnixStyle;
                }
                //Иначе стиль Windows
                else if (s.Length > 8
                    && Regex.IsMatch(s.Substring(0, 8), "[0-9]{2}-[0-9]{2}-[0-9]{2}"))
                {
                    return FileListStyle.WindowsStyle;
                }
            }
            return FileListStyle.Unknown;
        }

        //Если сервер работает на nix-ах
        private FileStruct ParseFileStructFromUnixStyleRecord(string record)
        {
            //Предположим. тчо запись имеет формат dr-xr-xr-x   1 owner    group    0 Nov 25  2002 bussys
            FileStruct f = new FileStruct();
            if (record[0] == '-' || record[0] == 'd')
            {// правильная запись файла
                string processstr = record.Trim();
                f.Flags = processstr.Substring(0, 9);
                f.IsDirectory = (f.Flags[0] == 'd');
                processstr = (processstr.Substring(11)).Trim();
                //отсекаем часть строки
                _cutSubstringFromStringWithTrim(ref processstr, ' ', 0);
                f.Owner = _cutSubstringFromStringWithTrim(ref processstr, ' ', 0);
                f.CreateTime = getCreateTimeString(record);
                //Индекс начала имени файла
                int fileNameIndex = record.IndexOf(f.CreateTime) + f.CreateTime.Length;
                //Само имя файла
                f.Name = record.Substring(fileNameIndex).Trim();
            }
            else
            {
                f.Name = "";
            }
            return f;
        }

        private string getCreateTimeString(string record)
        {
            //Получаем время
            string month = "(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)";
            string space = @"(\040)+";
            string day = "([0-9]|[1-3][0-9])";
            string year = "[1-2][0-9]{3}";
            string time = "[0-9]{1,2}:[0-9]{2}";
            Regex dateTimeRegex = new Regex(month + space + day + space + "(" + year + "|" + time + ")", RegexOptions.IgnoreCase);
            Match match = dateTimeRegex.Match(record);
            return match.Value;
        }

        private string _cutSubstringFromStringWithTrim(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;
        }
    }
}

和这个空白

//Построение дерева файловой системы ftp сервера 
private static void ListDirectory(TreeView treeView, string Host, string UserName, string password)
{
    Ftp_Client ftp = new Ftp_Client();
    ftp.Host = Host;
    ftp.UserName = UserName;
    ftp.Password = password;
    treeView.Nodes.Clear();

    var stack = new Stack<TreeNode>();
    var rootDirectory = DOMAIN;
    var node = new TreeNode(rootDirectory) { Tag = "/" };
    stack.Push(node);

    while (stack.Count > 0)
    {
        try
        {
            var currentNode = stack.Pop();
            var directoryInfo = ftp.ListDirectory((string)currentNode.Tag);
            foreach (var directory in directoryInfo)
            {
                if (directory.IsDirectory && directory.Name!="?") {
                    var childDirectoryNode = new TreeNode(directory.Name) { Tag = currentNode.Tag+directory.Name+'/'};
                    currentNode.Nodes.Add(childDirectoryNode);
                    stack.Push(childDirectoryNode);
                }
            }
            foreach (var file in directoryInfo)
                if (!file.IsDirectory && file.Name != "?")
                    currentNode.Nodes.Add(new TreeNode(file.Name) { Tag = currentNode.Tag + file.Name + "/f"}); ; //пометка f в конце пути означает, что это файл!
        }
        catch(Exception ex)
        {
            MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

    treeView.Nodes.Add(node);
}

打电话给

ListDirectory(treeView1,DOMAIN,USER,PASS);