Apache FTPClient:将文本从内存写入FTP服务器上的文件

问题描述 投票:1回答:2

我的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()"]

问题:如何使用库将文本写入文件,并事先创建新文件(如有必要)?


[Edit:相反,我也尝试将文本保存到外部存储,然后上传整个文件:

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.
java android ftp apache-commons-net
2个回答
1
投票

对我来说,您的代码有效,所以我不知道为什么它不适合您。

无论如何,随着FTPClient.storeFile的发挥,您可以将其与内存流一起使用,如下所示:

FTPClient.storeFile

0
投票

[正如MartinPrikryl在评论中已经提到的,不要叫InputStream is = new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8)); ftpClient.storeFile(filename, is); ,这是enterRemotePassiveMode每次都是OutputStream os的原因。

我为解决此问题所做的操作(创建但未写入文件):

  1. 由于不必要,我删除了null
  2. 我使用的BufferedReader看起来还不错,但是值得在发送之前检查它是否还好。这是因为在Android Studio中进行大量构建(我在其他IDE中也经历过)可以使变量“卡住”其旧值,可以通过清理项目和/或重新启动Android Studio来修复变量。]
  3. 工作代码:

text

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 } 内的第一段也可以用MartinPrikryl的代码(if代替storeFile)替换。

© www.soinside.com 2019 - 2024. All rights reserved.