Laden...

Bei Download von einem FTP Server werden nicht alle Daten heruntergeladen

Erstellt von tobias.billen vor 5 Jahren Letzter Beitrag vor 5 Jahren 1.168 Views
T
tobias.billen Themenstarter:in
8 Beiträge seit 2018
vor 5 Jahren
Bei Download von einem FTP Server werden nicht alle Daten heruntergeladen

Hallo zusammen,

ich möchte gerne eine Routine schreiben, die bestimmte Filetypen (zB pdf, txt) von einem FTP Server herunterläd. Dazu übergebe ich der untenstehenden Klasse die Werte host (= vollständige Adresse des FTP Server), username (= Benutzernamen für den Login auf dem FTP Server) und das Passwort (=pw) hierfür. Außerdem bekommt die Klasse den Zielpath zugewiesen (Für dieses Beispiel existiert bei mir unter C:\ ein Ordner Namens "Test".
Mit diesen Daten untersucht die Klasse welche Dateien es auf dem FTP Server gibt (

folder = reader.ReadToEnd();

). Dieser String wird nun nach entsprechenden Dateinamen gefiltert (

if (inhalt.Contains(".pdf") || inhalt.Contains(".txt"))

) und dann wird **versucht **die Datei herunterzuladen (= private void download(string ftp_file, string file)).

Mein Problem ist: Es bleibt oft beim versuch (Es werden nur ca. 50% der Daten heruntergeladen.). Wie ihr sehen könnt, habe ich bereits dieses Problem in zwei Teile unterteilt (Suchen der Dateien auf dem FTP Server und Download der gefundenen Daten).

Könnt ihr bitte einen Tipp geben, wo ich einen "Fehler" in meinem Code habe? Anbei die komplette Klasse. Sollte ich dieses Thema im falschen Forum erstellt haben, bitte ich um Nachsicht.


using System;
using System.IO;
using System.Net;

namespace Download_FTP
{
    class FTP_Download
    {
        string host, username, pw, folder, path;
        
        public FTP_Download(string host, string username, string pw, string path)
        {
            this.pw = pw;
            this.username = username;
            this.host = host;
            this.path = path;
        }

        public override string ToString()
        {
            for (int i =  507; i < 511; i++)
            {
                getFolder("/" + i + "/");
            }
                
            return "Ende";
        }

        private void getFolder(string path)
        {
            try
            {
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(this.host + path);
                request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;

                request.Credentials = new NetworkCredential(this.username, this.pw);

                FtpWebResponse response = (FtpWebResponse)request.GetResponse();

                Stream responseStream = response.GetResponseStream();
                StreamReader reader = new StreamReader(responseStream);

                folder = reader.ReadToEnd();

                reader.Close();
                response.Close();

                folder = folder.Replace('-', ' ');

                foreach (String inhalt in folder.Split(" "))
                {
                    if (inhalt.Contains(".pdf") || inhalt.Contains(".txt"))
                    {
                        download(this.host + path + inhalt, inhalt);

                    }
                }               
            }
            catch (Exception e)
            {
                Console.WriteLine("Es gibt Probleme mit " + this.host + path + "   " + e.Message);
            }
        }

        private void download(string ftp_file, string file)
        {
            String[] tmp = ftp_file.Split("/");
            String final_file = this.path + tmp[tmp.Length - 2] + "/" + file;
            Console.WriteLine("\n\nTry to download " + final_file);
            try
            {
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftp_file);
                request.Credentials = new NetworkCredential(this.username, this.pw);
                request.Method = WebRequestMethods.Ftp.DownloadFile;

                using (Stream ftpStream = request.GetResponse().GetResponseStream())
                using (Stream fileStream = File.Create(final_file))
                {
                    byte[] buffer = new byte[10240];
                    int read;
                    while ((read = ftpStream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        fileStream.Write(buffer, 0, read);
                    }
                }
                Console.WriteLine("Pass: " + final_file + " => File: " + file +"\n\n");
                request.KeepAlive = false;
            }


            catch(Exception e)
            {
                Console.WriteLine(" Fail:   " + final_file + " couldn't be downloaded. "   +  e.Message +"\n\n");
            }

        }

    }
}



Res Servea Verum Gaudium

3.170 Beiträge seit 2006
vor 5 Jahren

Hallo,

setz mal das request.KeepAlive = false, bevor Du den Request abschickst. Im Nachhinein bringt das nichts mehr. Dann bleiben vermutlich noch Verbindungen offen - FTP-Server mögen das oft nicht so gerne.

Laut Doku wird sogar eine InvalidOperationException geworfen, wenn KeepAlive nach Aufruf von GetResponse noch geändert wird wird. Die müsstest Du mit dem Code eigentlich für jede Datei bekommen.

Zusätzlich noch eine Anmerkung:

using (Stream ftpStream = request.GetResponse().GetResponseStream())

Durch dieses using wird zwar der Stream disposed, aber nicht die WebResponse.
Das sollte zwar in diesem Zusammenhang keine Rolle spielen - besser wäre es trotzdem, wenn Du Close oder Dispose auf der Response aufrufst. Der ResponseStream wird dadurch dann mit entsorgt.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

T
tobias.billen Themenstarter:in
8 Beiträge seit 2018
vor 5 Jahren

Hallo MarsStein,

vielen Dank für Deine Antwort!

Ich habe versucht deine Tipps umzusetzten und habe folgendes Ergebnis (siehe unten). Leider kommt es jetzt immer noch vereinzelt vor das eine Exception > Fehlermeldung:

Unable to connect to the remote server .
Ich frage mich, ob ich deine Tipps falsch verstanden und/oder umgestzt habe oder habe ich noch ein anderen Fehler eingebaut?


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

namespace Download_FTP
{
    class FTP_Download
    {
        string host, username, pw, folder, path;
        
        public FTP_Download(string host, string username, string pw, string path)
        {
            this.pw = pw;
            this.username = username;
            this.host = host;
            this.path = path;
        }

        public override string ToString()
        {
            String s = "";
            for (int i =  507; i < 511; i++)
            {
                s += "\n\n" + getFolder("/" + i + "/") + "\n\n";
            }
                
            return s;
        }

        private string getFolder(string path)
        {
            string s = "";
            try
            {
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(this.host + path);
                request.KeepAlive = false;
                request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;

                request.Credentials = new NetworkCredential(this.username, this.pw);

                FtpWebResponse response = (FtpWebResponse)request.GetResponse();

               using (Stream responseStream = response.GetResponseStream())
                {
                    using (StreamReader reader = new StreamReader(responseStream))
                    {
                        folder = reader.ReadToEnd();
                        reader.Close();
                        response.Close();                        
                    }
                    responseStream.Close();
                }
                foreach (String inhalt in getName(folder))
                {
                    s += download(this.host + path + inhalt, inhalt);
                }

                              
            }
            catch (Exception e)
            {
                s += "\n\nEs gibt Probleme mit " + this.host + path + "   " + e.Message + "\n\n";
            }
            return s;
        }

        private List<string> getName(string name)
        {
            List<string> files = new List<string>();
            string[] s = name.Split(' ');
            foreach (string t in s)
            {
                if (t.Contains(".pdf") || t.Contains(".jpg") )
                {
                    files.Add(t.Replace("-rw----r--", ""));
                }
            }

            return files;         
        }

        private string download(string ftp_file, string file)
        {

            String[] tmp = ftp_file.Split("/");
            String final_file = this.path + tmp[tmp.Length - 2] + "/" + file;
            string s = "";
            try
            {
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftp_file);
                request.KeepAlive = false;
                request.Credentials = new NetworkCredential(this.username, this.pw);
                request.Method = WebRequestMethods.Ftp.DownloadFile;

                using (Stream ftpStream = request.GetResponse().GetResponseStream())
                {
                    using (Stream fileStream = File.Create(final_file))
                    {
                        byte[] buffer = new byte[10240];
                        int read;
                        while ((read = ftpStream.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            fileStream.Write(buffer, 0, read);
                        }
                        ftpStream.Close();
                    }
                    ftpStream.Close();
                }
               
                s += "\n\nPass: " + final_file + " => File: " + file +"\n\n";
                
            }


            catch(Exception e)
            {
                s += "\n\nFail:   " + final_file + " couldn't be downloaded. "   +  e.Message +"\n\n";
            }

            return s;

        }

    }
}

Res Servea Verum Gaudium