Datei-Download von FTP-Server

  • 5 Antworten
  • Neuester Beitrag
Diskutiere Datei-Download von FTP-Server im Android App Entwicklung im Bereich Betriebssysteme & Apps.
S

Schnicke

Neues Mitglied
Hallo zusammen,
ich bin am verzweifeln. Ich möchte eine Textdatei von einem FTP-Server runterladen. Hier der Code:

Code:
public class UpDown extends Activity{
...
  class Download extends AsyncTask<String, Void, String> {
...
        private String connect() {
            // Verbinden und einloggen
...
           // Da kommts her...
                String srcPath = "/Ordner/Unterordner/Textdatei.txt";

           // ... und da solls hin
                String destPath = Environment.getExternalStorageDirectory()
                        .toString() + "/Datei";
               
                if (ftpDownload(srcPath, destPath)) {
                    Log.d(TAG, "download done");
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
            if (ftpDisconnect()) {
                Log.d(TAG, "disconnected");
            }
            return "placeholder";
        }
    }
   
    public boolean ftpDownload(String srcFilePath, String desFilePath) {
        boolean status = false;
       
        try {
            FileOutputStream desFileStream = new FileOutputStream(desFilePath);
            status = ftpClient.retrieveFile(srcFilePath, desFileStream);
            desFileStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            Log.d(TAG, "download failed");
        }
   return status;
  }  
}
Bis vor
Code:
FileOutputStream desFileStream = new FileOutputStream(desFilePath);
läuft das Programm. Der FileOutputStream wird nicht mehr erstellt. Fehlermeldung:
Code:
05-23 15:14:01.867: W/System.err(18884): 
java.io.FileNotFoundException: /storage/emulated/0/Datei: 
open failed: EISDIR (Is a directory)
Was ist hier falsch? Ich freue mich über jede Hilfe :)
 
B

burgerohnealles

Fortgeschrittenes Mitglied
klick mich erster Link, könnte dir vllt helfen
=> Guck mal, ob "/storage/emulated/0/Datei" existiert und ein Ordner ist
 
Zuletzt bearbeitet:
S

Schnicke

Neues Mitglied
Danke euch für die Antworten :)

Google habe ich bis zum Gehtnichtmehr befragt und eure Links kenne ich schon und habe sie auch schon ausprobiert (bin trotzdem dankbar) :) Mein Problem hat sich nun geändert.

Ein Fehler war, dass der Pfad zur Datei, die heruntergeladen werden soll nicht in einem Pfad angegeben werden darf, sondern relativ zum aktuellen Arbeitsverzeichnis. Also bin ich ins aktuelle Verzeichnis auf dem FTP-Server gewechselt und habe nur den Dateinamen als Sourcefile angegeben:
Code:
private String connect() {
...
  if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                    Log.d(TAG, "could not connect to host");
                } else {
                    Log.d(TAG, "connected to host");
                }
                Log.d(TAG, "Current dir: "+ftpGetCurrentWorkingDirectory());
                ftpChangeDirectory("/Ordner/Unterordner/");
                Log.d(TAG, "Current dir: "+ftpGetCurrentWorkingDirectory());
                // Hier kommts her...
                String srcPath = "download.txt";
                //... und da solls hin
                String destPath = Environment.getExternalStorageDirectory()
                        .toString() + "/Datei/download.txt";
....
}
Das geht alles. Das Problem tritt hier auf:

Code:
public boolean ftpDownload(String srcFilePath, String desFilePath) {
        Log.d(TAG, "ftpDownload");
        boolean status = false;
        String status2 = Environment.getExternalStorageState();
        Log.d(TAG, "status2: " + status2);
        Log.d(TAG, "srcFilePath: "+srcFilePath);
        // Prüfen, ob ich auch wirklich, richtig, ehrlich immernoch im richtigen  Verzeichnis bin
        Log.d(TAG, "curr dir: "+ftpGetCurrentWorkingDirectory());
        try {
            FileOutputStream desFileStream = new FileOutputStream(desFilePath);
            Log.d(TAG, "fileStream");
            status = ftpClient.retrieveFile(File.separator+srcFilePath, desFileStream);
           
[B]// Den Fehler 550 bekomme ich jetzt, laut apache RFC: File unavailable 
            if(ftpClient.getReplyCode() == 550){
                Log.d(TAG, "error 550");
            }[/B]
return status;
            ...}
Die Datei liegt definitiv auf dem Server. Die Apache FTP-Api sagt nun, dass manche FTP-Methoden nicht alle ihre Aktionen komplett ausführen. Sollte für den Fall eigentlich irrelevant sein, ich habs aber trotzdem probiert:
Code:
...status = ftpClient.retrieveFile(File.separator+srcFilePath, desFileStream);
            ftpClient.completePendingCommand();
...
Das Einfügen dieser Methode führt nun dazu, dass das Programm in der completePending-Methode hängen bleibt.

Wisst ihr dazu vielleicht etwas?

UPDATE:
Habe nun folgendes geändert:
Code:
try {
            FileOutputStream desFileStream = new FileOutputStream(desFilePath);
            InputStream in = ftpClient.retrieveFileStream(srcFilePath);
            Util.copyStream(in, desFileStream);
...
}
Jetzt kommt beim InputStream der Fehler 425: Can't open data connection for transfer. Ich weiß nicht mehr weiter... Mit dem Total Commander kann ich ohne Probleme Dateien zwischen dem FTP-Server und meinem Rechner hin und her schieben. Wo ist da nur der Fehler?
Normaler Java-Code macht keine Probleme. Was muss ich Android da verklickern?
 
Zuletzt bearbeitet:
B

burgerohnealles

Fortgeschrittenes Mitglied
Ja, "File.separator+srcFilePath" muss nur "srcFilePath", sonst würde er die Datei im Root-Verzeichnis suchen, wo sie (wahrscheinlich) nicht existiert, falls doch dann ist es die falsche Datei.

Ich gehe mal davon aus, dass die den Modus nicht auf Passiv gesetzt hast. Versuch mal vor dem Aufruf von ftpDownload bzw. an den Anfang dieser Funktion folgendes einzufügen: "ftpClient.enterLocalPassiveMode();". Wenns dann immer noch nicht geht häng auch mal das dran: "ftpClient.setFileType(FTP.BINARY_FILE_TYPE)". Wenns dann immer noch net klappt poste mal den kompletten Source-Code (nicht vergessen das PW zu entfernen!), dann können ich und die anderen hier dir eher helfen.
 
S

Schnicke

Neues Mitglied
Hab den Fehler gefunden: Ich hatte irgendwann mal die Endung txt beim sourcefile rausgenommen, dann Änderungen gemacht, und wieder vergessen rein zu nehmen.
Es ist spät...
Danke euch jedenfalls trotzdem!! Der Vollständigkeit halber der Code:

Code:
public class UpDown extends Activity {
    public final static String TAG = "Upload/Download";
    FTPClient ftpClient = new FTPClient();
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_up_down);
  }

    public void down(View v) {
        Download d = new Download();
        d.execute();
    }

    public void up(View v) {
        Upload d = new Upload();
        d.execute();
    }

    class Download extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... params) {
            Log.d(TAG, "doinbackground_Download");
            return connect();
        }

        private String connect() {
            try {
                ftpClient.connect("host.adresse.de");
                ftpClient.enterLocalPassiveMode();
                ftpClient.login("UserID", "passwort");
                ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
                
                if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                    Log.d(TAG, "could not connect to host");
                } else {
                    Log.d(TAG, "connected to host");
                }
                Log.d(TAG, "Current dir: "+ftpGetCurrentWorkingDirectory());
                ftpChangeDirectory("/Order1/Ordner2/");
                Log.d(TAG, "Current dir: "+ftpGetCurrentWorkingDirectory());
                String srcPath = "download.txt";
                String destPath = Environment.getExternalStorageDirectory()
                        .toString() + "/myDirectory/download.txt";

                if (ftpDownload(srcPath, destPath)) {
                    Log.d(TAG, "download done");
                } else {
                    Log.d(TAG, "download incomplete");
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
            if (ftpDisconnect()) {
                Log.d(TAG, "disconnected");
            } 
            return "placeholder";

        }

    }

    public boolean ftpDownload(String srcFilePath, String desFilePath) {
        Log.d(TAG, "ftpDownload");
        boolean status = false;
        String status2 = Environment.getExternalStorageState();
        Log.d(TAG, "status2: " + status2);
        Log.d(TAG, "srcFilePath: "+srcFilePath);
        Log.d(TAG, "curr dir: "+ftpGetCurrentWorkingDirectory());
        try {
            FileOutputStream desFileStream = new FileOutputStream(desFilePath);
            Log.d(TAG, "fileStream");
            status = ftpClient.retrieveFile(srcFilePath, desFileStream);
            if(!status){
                Log.d(TAG, "0");
            }
            /*if(ftpClient.completePendingCommand()){
                Log.d(TAG, "complete ... true");
            }*/
            Log.d(TAG, "reply code: "+ftpClient.getReplyCode());
            Log.d(TAG, "retrieved");
            desFileStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();

        } catch (Exception e) {
            Log.d(TAG, "download failed");
        }

        return status;
    }

    public boolean ftpChangeDirectory(String directory_path) {
        Log.d(TAG, "ftpChangeDirectory");
        try {
            return ftpClient.changeWorkingDirectory(directory_path);
        } catch (Exception e) {
            Log.d(TAG, "Error: could not change directory to " + directory_path);
        }

        return false;
    }

    public String ftpGetCurrentWorkingDirectory() {
        try {
            String workingDir = ftpClient.printWorkingDirectory();
            return workingDir;
        } catch (Exception e) {
            Log.d(TAG, "Error: could not get current working directory.");
        }

        return null;
    }

    public boolean ftpDisconnect() {
        try {
            ftpClient.logout();
            ftpClient.disconnect();
            return true;
        } catch (Exception e) {
            Log.d(TAG, "Error occurred while disconnecting from ftp server.");
        }

        return false;
    }
}