Apache FTPClient: запись текста из памяти в файл на FTP-сервере - PullRequest
1 голос
/ 23 апреля 2020
Приложение

My Android (мин. API 24, целевой API 27, Java 8) использует Apache FTPClient для подключения к FTP-серверу. В данный момент я пытаюсь записать некоторый текст в файл на сервере (файл не существует на телефоне!), Но не получается:

login(); //logs in and leaves the connection open
ftpClient.enterLocalPassiveMode();

if(ftpClient.changeWorkingDirectory(folder)) {
    OutputStream os = ftpClient.storeFileStream(File.separator+filename);
    BufferedWriter bw = new BufferedWriter((new OutputStreamWriter(os,StandardCharsets.UTF_8)));
    bw.write(text);
    bw.close();

    if(ftpClient.completePendingCommand()) {
        //Success!
    } else {
        //Failed
    }
} else {
    //Show error because folder doesn't exist
}

Файл обычно не существует на сервер и, пока он создается, он всегда пуст.

Журнал для него:

CWD 
250 CWD command successful.
PWD
257 "/" is current directory.
PASV
227 Entering Passive Mode ([IP here]).
STOR /blabla9.txt
125 Data connection already open; Transfer starting.
226 Transfer complete. [called because of "completePendingCommand()"]

Вопрос: Как записать текст в файл, используя библиотека, заранее создающая новый файл (при необходимости)?


Редактировать: Вместо этого я также попытался сохранить текст во внешнем хранилище, а затем загрузить весь файл:

login(); //logs in and leaves the connection open
ftpClient.enterLocalPassiveMode();

if(ftpClient.changeWorkingDirectory(folder)) {
    ftpClient.setFileType(FTP.ASCII_FILE_TYPE);
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
    boolean result = ftpClient.storeFile(filename, bis);
    bis.close();

    if(result) {
        //Success!
    } else {
        //Failed
    }
} else {
    //Show error because folder doesn't exist
}

Это работает, но это только временное решение, поскольку сначала требуется записать файл во внешнее хранилище, а затем снова удалить его после загрузки.

Журнал для этого версия:

CWD 
250 CWD command successful.
PWD
257 "/" is current directory.
TYPE A
200 Type set to A.
PASV
227 Entering Passive Mode ([IP here]).
STOR blabla11.txt
125 Data connection already open; Transfer starting.
226 Transfer complete.

Ответы [ 2 ]

1 голос
/ 24 апреля 2020

Для меня ваш код работает, поэтому я не знаю, почему он не работает для вас.

В любом случае, так как FTPClient.storeFile работает у вас - вы можете использовать его с -поток памяти, как это:

InputStream is = new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8));
ftpClient.storeFile(filename, is);
0 голосов
/ 28 апреля 2020

Как уже упоминал MartinPrikryl в комментариях, не звоните enterRemotePassiveMode, это было причиной того, что OutputStream os был null каждый раз.

Что я сделал, чтобы решить проблему (файл был создан но не записано):

  1. Я удалил BufferedReader, так как он не нужен.
  2. Я использую text выглядел хорошо, но стоит проверить, что все еще хорошо, верно перед отправкой. Это связано с тем, что сборка большого количества в Android Studio (я также испытывал это в других IDE) может привести к тому, что переменные «застрянут» со своим старым значением, которое можно исправить, очистив проект и / или перезапустив Android Studio.

Рабочий код:

login(); //logs in and leaves the connection open
ftpClient.enterLocalPassiveMode();

if(ftpClient.changeWorkingDirectory(folder)) {
    OutputStream os = ftpClient.storeFileStream(File.separator+filename);
    OutputStreamWriter osw = new OutputStreamWriter(os,StandardCharsets.UTF_8);
    osw.write(text);
    osw.close(); //Better use this in a "finally"

    if(ftpClient.completePendingCommand()) {
        //Success!
    } else {
        //Failed
    }
} else {
    //Show error because folder doesn't exist
}

Первый абзац внутри if также можно заменить кодом MartinPrikryl (storeFile вместо storeFileStream).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...