简体   繁体   中英

How do I pull the file locations (path and filename) for all files at a given FTP address?

Hi and thanks for looking!

Background

I need to pull the file locations (path and filename) for all files at a given FTP address.

For files on a mapped network or local drive, this code would work:

foreach(string fileName f in Directory.GetFiles("C\\:SomeDirectory"), "*.*",
                                     SearchOption.AllDirectories)
{
    //do stuff with each file found
}

But this will NOT work over an FTP connection. I have already found this MS documentation which covers the establishing of an FTPWebRequest, but it does not show me how to loop through each file found (in all nested directories as well).

I am using C# within a forms app.

Question

How do I accomplish this:

foreach(string fileName f in Directory.GetFiles("C\\:SomeDirectory"), "*.*",
                                         SearchOption.AllDirectories)
    {
        //do stuff with each file found
    }

With an FTP connection?

Many thanks!!

UPDATE / Final Answer

Special thanks to @sunk for getting this going. I made a minor tweek to his code that makes it fully recursive so that it can drill into nested folders. Here is the final code:

       //A list that holds all file locations in all folders of a given FTP address:
        List<string> fnl= new List<string>(); 

        //A string to hold the base FTP address:
        string ftpBase = "ftp://[SOME FTP ADDRESS]";

        //A button-click event.  Can be a stand alone method as well
        private void GetFileLocations(object sender, EventArgs e)
        {
            //Get the file names from the FTP location:
            DownloadFileNames(ftpBase);

            //Once 'DownloadFileNames' has run, we have populated 'fnl'
            foreach(var f in fnl)
            {
                //do stuff
            }        
        }

        //Gets all files in a given FTP address.  RECURSIVE METHOD:
        public void DownloadFileNames(string ftpAddress)
        {
            string uri = ftpAddress;
            FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri);
            reqFTP.Credentials = new NetworkCredential("pella", "PellaWA01!");
            reqFTP.EnableSsl = false;
            reqFTP.KeepAlive = false;
            reqFTP.UseBinary = true;
            reqFTP.UsePassive = true;
            reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
            FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
            Stream responseStream = response.GetResponseStream();
            List<string> files = new List<string>();
            StreamReader reader = new StreamReader(responseStream);
            while (!reader.EndOfStream)
                files.Add(reader.ReadLine());
            reader.Close();
            responseStream.Dispose();

            //Loop through the resulting file names.
            foreach (var fileName in files)
            {
                var parentDirectory = "";

                //If the filename has an extension, then it actually is 
                //a file and should be added to 'fnl'.            
                if (fileName.IndexOf(".") > 0)
                {
                    fnl.Add(ftpAddress.Replace("ftp://pella.upload.akamai.com/140607/pella/",              "http://media.pella.com/") + fileName);
                }
                else
                {
                //If the filename has no extension, then it is just a folder. 
                //Run this method again as a recursion of the original:
                    parentDirectory += fileName + "/";
                    try
                    {
                        DownloadFileNames(ftpAddress + parentDirectory);
                    }
                    catch (Exception)
                    {
                        //throw;
                    }
                }
            }
        }

First of all, you have to get the files name local on your machine using FTPWebRequest.

WebRequestMethods.Ftp.ListDirectory;

then use foreach {};

Here is the code:-

public List<string> DownloadFileNames()
        {
                string uri = "ftp://" + ftpServerIP + "/";
                FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri);
                reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
                reqFTP.EnableSsl = true;
                reqFTP.KeepAlive = false;
                reqFTP.UseBinary = true;
                reqFTP.UsePassive = Settings.UsePassive;
                reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
                ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);
                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
                Stream responseStream = response.GetResponseStream();
                List<string> files = new List<string>();
                StreamReader reader = new StreamReader(responseStream);
                while (!reader.EndOfStream)
                    files.Add(reader.ReadLine());
                reader.Close();
                responseStream.Dispose();
                return files;
        }

Now you have the List:-

List<string> FileNameList = DownloadFileNames();
foreach (var fileName in FileNameList)
{

}

the ListDirectoryDetails command used in the example just returns a string. You will have to manually parse it to build a list of files and subdirectories.

Found at http://social.msdn.microsoft.com/Forums/en/ncl/thread/079fb811-3c55-4959-85c4-677e4b20bea3

    string[] files = GetFileList();
    foreach (string file in files)
    {
        Download(file);
    }

    public string[] GetFileList()
    {
        string[] downloadFiles;
        StringBuilder result = new StringBuilder();
        WebResponse response = null;
        StreamReader reader = null;
        try
        {
            FtpWebRequest reqFTP;
            reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/"));
            reqFTP.UseBinary = true;
            reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
            reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
            reqFTP.Proxy = null;
            reqFTP.KeepAlive = false;
            reqFTP.UsePassive = false;
            response = reqFTP.GetResponse();
            reader = new StreamReader(response.GetResponseStream());
            string line = reader.ReadLine();
            while (line != null)
            {
                result.Append(line);
                result.Append("\n");
                line = reader.ReadLine();
            }
            // to remove the trailing '\n'
            result.Remove(result.ToString().LastIndexOf('\n'), 1);
            return result.ToString().Split('\n');
        }
        catch (Exception ex)
        {
            if (reader != null)
            {
                reader.Close();
            }
            if (response != null)
            {
                response.Close();
            }                
            downloadFiles = null;
            return downloadFiles;
        }
    }

    private void Download(string file)
    {                       
        try
        {                
            string uri = "ftp://" + ftpServerIP + "/" + remoteDir + "/" + file;
            Uri serverUri = new Uri(uri);
            if (serverUri.Scheme != Uri.UriSchemeFtp)
            {
                return;
            }       
            FtpWebRequest reqFTP;                
            reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/" + remoteDir + "/" + file));                                
            reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);                
            reqFTP.KeepAlive = false;                
            reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;                                
            reqFTP.UseBinary = true;
            reqFTP.Proxy = null;                 
            reqFTP.UsePassive = false;
            FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
            Stream responseStream = response.GetResponseStream();
            FileStream writeStream = new FileStream(localDestnDir + "\" + 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);
            }                
            writeStream.Close();
            response.Close(); 
        }
        catch (WebException wEx)
        {
            MessageBox.Show(wEx.Message, "Download Error");
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Download Error");
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM