štvrtok, 21 jún 2012 13:02 Written by 3090 times
Rate this item
(3 votes)

c# - Ako stiahnuť súbory z ftp

V nasledujúcom príklade si ukážeme ako stiahnuť celý adresár (folder) z ftp servera pomocou c#.

V prvok kroku musíme stiahnuť zoznam súborov v nami zadanom adresári na ftp. Na to použijeme nasledujúci kód:

 

                FtpWebRequest reqFTP;
                reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServer + "/"+directory));
                reqFTP.UseBinary = true;
                reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
                reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
                reqFTP.Proxy = null;
                reqFTP.KeepAlive = false;                
                
                using (FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse())
                {
                    using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                    {
                        name = reader.ReadToEnd();
                    }
                }

Ak nastavíme reqFTP.Method = WebRequestMethods.Ftp.ListDirectory; ,tak sa nám stiahne zoznam súborov v tvare:

 

a
beeeee
config.xml
Copy (2) of config.xml

Z tohto tvaru však nevieme určiť či sa jedná o adresár alebo súbor. Ak to chceme rozlíšiť, musíme nastaviť reqFTP.Method = WebRequestMethods.Ftp.ListDirectoryDetails;. Pomocou tejto metódy sa stiahne zoznam súborov v tvare:

drwxr-xr-x   1 ftp      ftp             0 Jun 20 11:38 a
drwxr-xr-x   1 ftp      ftp             0 Jun 20 13:28 beeeee
-rw-r--r--   1 ftp      ftp           690 Oct 08  2009 config.xml
-rw-r--r--   1 ftp      ftp           690 Oct 08  2009 Copy (2) of config.xml

Z nasledujúceho vidíme, že ak je to adresár, riadok sa začína "d". Z tohto postupu je však dosť naročné vyseparovať názov súboru. Preto názvy súborov použijeme z prvého kroku a to, či sa jedná o adresár, z druhého kroku. Možno existuje aj iné riešenie, ale ja som to riešil takto.

Vysledný zdrojový kód v c# :

using System;
using System.Collections;
using System.IO;
using System.Net;
using System.Text;
namespace projectik
{
    /// <summary>
    /// ftpFName
    /// </summary>
    internal class ftpFName
    {
        public ftpFName(string name, bool isFolder)
        {
            this.name = name;
            this.isFolder = isFolder;
        }
        public bool isFolder { get; set; }
        public string name { get; set; }
    }
    /// <summary>
    /// FtpClass
    /// </summary>
    internal class FtpClass
    {
        private string ftpServerIP { get; set; }
        private string ftpUserID { get; set; }
        private string ftpPassword { get; set; }
        private string errorMessage = String.Empty;
        private ArrayList downloadedFiles = new ArrayList();
        /// <summary>
        /// konstruktor FTPClass
        /// </summary>
        /// <param name="ftpServerIP"></param>
        /// <param name="ftpUserID"></param>
        /// <param name="ftpPassword"></param>
        public FtpClass(string ftpServerIP, string ftpUserID, string ftpPassword)
        {
            try
            {
                this.ftpServerIP = ftpServerIP;
                this.ftpUserID = ftpUserID;
                this.ftpPassword = ftpPassword;
            }
            catch
            {
            }
        }
        /// <summary>
        /// Vlastnost na vratenie stiahnutych suborov z FTP
        /// </summary>
        public string[] DownloadedFiles
        {
            get
            {
                return (string[])downloadedFiles.ToArray(typeof(string));
            }
        }
        /// <summary>
        /// Vrati aktualnu chybu
        /// </summary>
        /// <returns></returns>
        public string GetErrorMessage()
        {
            return errorMessage;
        }
        /// <summary>
        /// Metoda na stiahnutie vsetkych suborov a adresarov na ftp
        /// </summary>
        /// <param name="directory">adresar na ftp</param>
        /// <param name="destiny">ka sa to ma ulozit</param>
        /// <returns>true/false</returns>
        public bool downloadDirectory(string directory, string destiny)
        {
            try
            {
                string path = Path.Combine(destiny, directory);
                bool status = false;
                //ak adresar neexistuje ,tak ho vytvorim
                if (Directory.Exists(path) != true)
                {
                    Directory.CreateDirectory(path);
                }
                directory = directory.TrimEnd(new char[] { '\\', '/' }) + "/";
                //ziskanie vsetkych suborov v adresary na ftp
                ftpFName[] subory = this.getFileList(directory);
                foreach (ftpFName s1 in subory)
                {
                    if (s1.isFolder)
                    {
                        status = this.downloadDirectory(directory + s1.name + "/", destiny);
                        if (status != true)
                        {
                            return false;
                        }
                        continue;
                    }
                    status = this.downloadFile(directory + s1.name, path);
                    if (status != true)
                    {
                        return false;
                    }
                }
            }
            catch (Exception ex1)
            {
                this.errorMessage = ex1.Message;
                return false;
            }
            return true;
        }
        /// <summary>
        /// ziskanie vsetkych suborov v adresary na ftp
        /// </summary>
        /// <param name="directory"></param>
        /// <returns>true/false</returns>
        private ftpFName[] getFileList(string directory)
        {
            ArrayList fileAndFolder = new ArrayList();
            StringBuilder result = new StringBuilder();
            string name, detailsname;
            string[] nameFiles, detailsNameFiles;
            try
            {
                FtpWebRequest reqFTP;
                reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/" + directory));
                reqFTP.UseBinary = true;
                reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
                reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
                reqFTP.Proxy = null;
                reqFTP.KeepAlive = false;
                reqFTP.UsePassive = false;
                using (FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse())
                {
                    using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                    {
                        name = reader.ReadToEnd();
                    }
                }
                nameFiles = name.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
                reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/" + directory));
                reqFTP.UseBinary = true;
                reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
                reqFTP.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
                reqFTP.Proxy = null;
                reqFTP.KeepAlive = false;
                reqFTP.UsePassive = false;
                using (FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse())
                {
                    using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                    {
                        detailsname = reader.ReadToEnd();
                    }
                }
                detailsNameFiles = detailsname.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
                for (int i = 0; i < detailsNameFiles.Length; i++)
                {
                    fileAndFolder.Add(new ftpFName(nameFiles[i], detailsNameFiles[i].StartsWith("d")));
                }
                return (ftpFName[])fileAndFolder.ToArray(typeof(ftpFName));
            }
            catch (Exception ex1)
            {
                this.errorMessage = ex1.Message;
                return null;
            }
        }
        /// <summary>
        /// Stiahnutie jedneho suboru z ftp
        /// </summary>
        /// <param name="file">subor na stiahnutie</param>
        /// <param name="destiny">Kam ulozit subor</param>
        /// <returns></returns>
        private bool downloadFile(string file, string destiny)
        {
            try
            {
                FtpWebRequest reqFTP;
                reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/" + file));
                reqFTP.UseBinary = true;
                reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
                reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
                reqFTP.Proxy = null;
                reqFTP.KeepAlive = false;
                reqFTP.UsePassive = false;
                using (FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse())
                {
                    using (Stream responseStream = response.GetResponseStream())
                    {
                        using (FileStream writeStream = new FileStream(Path.Combine(destiny, Path.GetFileName(file)), FileMode.Create))
                        {
                            int Length = 2048;
                            Byte[] buffer = new Byte[Length];
                            int bytesRead = responseStream.Read(buffer, 0, Length);
                            while (bytesRead > 0)
                            {
                                writeStream.Write(buffer, 0, bytesRead);
                                bytesRead = responseStream.Read(buffer, 0, Length);
                            }
                            //ulozim subor ,ktory bol vytvorený
                            this.downloadedFiles.Add(Path.GetFileName(file));
                        }
                    }
                }
            }
            catch (Exception ex1)
            {
                this.errorMessage = ex1.Message;
                return false;
            }
            return true;
        }
    }
}

Použitie :

 

                string ftpUserID = "root";
                string ftpPassword = "admin";
                string destinyLocalDirectory = @"c:\daco";
                FtpClass myFtpClass = new FtpClass(server, ftpUserID, ftpPassword);
                string dir = "ftpDirectory";
                bool status = myFtpClass.downloadDirectory(dir, destinyLocalDirectory);
                if (status != true)
                {
                    errorMessage = "Nepodarilo sa stiahnut vsetky data s ftp servera.\n"+myFtpClass.GetErrorMessage();
                    return false;
                }

 

 

 

Last modified on pondelok, 25 jún 2012 11:03
Ing.Jaroslav Vadel

Som zakladateľom www.projectik.eu.

Hrám sa na programátora, ktorý ovláda:

c#,cpp,java,unity3d,php,html,NI testand,NI Vision Builder,Cognex In-Sight,NI LabView

"Naprogramovať program, ktorý funguje vie každy. Ale to, že program funguje ešte neznamena, že je napísany správne "

Website: www.projectik.eu