Ich arbeite derzeit an einem kleinen Checklisten-Builder-Programm in Java. Ich möchte die erstellte Datei auf meinen FTP-Server (ftps) hochladen und herunterladen. Ich verwende den folgenden Code zum Herunterladen:

public static void downloadfile(){
    FTPSClient con = null;

    System.out.println("Download Status: 5%");
    try
    {
        System.out.println("Download Status: 20%");
        con = new FTPSClient();
        con.connect(url);

        if (con.login(user, psw))
        {
            System.out.println("Download Status: 50%");
            con.enterLocalPassiveMode(); // important!
            con.setFileType(FTP.BINARY_FILE_TYPE);
            String data = "E:\\Downloads\\Testdokument.txt";

            OutputStream out = new FileOutputStream(new File(data));
            boolean result = con.retrieveFile("Testdokument.txt", out);
            out.close();
            System.out.println(result);
            if (result) {
                System.out.println("Download Status: 100%");
            } else if(result == false) {
                System.out.println("Download won't work");
            }
            con.logout();
            con.disconnect();
        }
    }
    catch (Exception e)
    {
        System.out.println("download failed");
        e.printStackTrace();
    }

}

Das Problem ist, dass der Download selbst gut funktioniert. Die heruntergeladene Datei ist jedoch leer. Wenn ich es mit einem Bild versuche, ist es nicht "lesbar". Der Upload funktioniert stattdessen einwandfrei. Ich verwende die Apache Common IO Library für die FTP-Funktion.

Wenn ich die Datei herunterlade, zeigt die Konsole den ersten Status 5%, 20%, 50% und nach dem Hinzufügen der falschen Anweisung funktioniert der Download nicht ...

Ich habe keine Ahnung, warum die Datei selbst heruntergeladen wird, aber keinen Inhalt enthält.

Irgendwelche Ideen?

0
AkEgo 8 Feb. 2020 im 14:29

3 Antworten

Beste Antwort

Sie machen Ressourcen in Java nicht richtig.

Jedes Mal, wenn Sie ein Objekt erstellen, das eine Ressource darstellt, müssen Sie es schließen. Sie öffnen ein neues FileOutputStream, und das ist eine Ressource. Alles, was AutoCloseable implementiert, ist definitiv eine Ressource, die Sie schließen müssen. Versuche dies:

try (OutputStream out = new FileOutputStream(data /* no need to wrap in File */)) {
    // do your stuff with out here
}

Zweiter Hinweis: Ihre Ausnahmebehandlung ist grausam. Bitte hören Sie auf, diesen häufigen Fehler zu machen. Ausnahmen enthalten 4 nützliche Informationen: Typ, Nachricht, Ablaufverfolgung und Ursache. Sie werfen buchstäblich 3 von 4 in den Mülleimer. Fügen Sie einfach throws Exception zu Ihrer Hauptmethode und Ihrer downloadFile Methode hinzu. Dies erspart Ihnen das Tippen und macht Ihre Fehlermeldungen viel nützlicher.

0
rzwitserloot 8 Feb. 2020 im 12:13

Ich habe die Lösung gefunden.

Ich habe die folgenden zwei Dinge hinzugefügt und es funktioniert jetzt

con.execPBSZ(0);
con.execPROT("P");

Keine Ahnung, wofür das steht, aber ich werde es herausfinden.

0
AkEgo 8 Feb. 2020 im 13:32

Ich weiß, dass diese Antwort nicht zum Thema gehört, aber ich möchte ein Beispiel für den Benutzer rzwitserloot bereitstellen, das zeigt, dass printStackTrace() keine wichtigen Informationen verbirgt. Dies würde nicht in einen Kommentar passen:

public class Main
{

    public static void doSomething()
    {
        int array[] = {1, 2, 3};
        int b = array[3];  // throws Exception
    }

    public static void test() throws Exception
    {
        try
        {
            doSomething();
        }
        catch (Exception e)
        {
            throw new Exception("something bad happened", e);
        }
    }

    public static void main(String[] args) throws Exception
    {
        try
        {
            test();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

Erzeugt Ausgabe:

java.lang.Exception: something bad happened
    at Main.test(Main.java:18)
    at Main.main(Main.java:26)
Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
    at Main.doSomething(Main.java:7)
    at Main.test(Main.java:14)
    ... 1 more

screenshot of output

Siehe auch die Dokumentation von Oracle: Spezifikation von printStackTrace

-1
Stefan 9 Feb. 2020 im 17:16