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



我的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.

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

无论如何,当FTPClient.storeFile工作时,您可以将其与内存流一起使用,如以下所示:

InputStream is = new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8));
ftpClient.storeFile(filename, is);

原来问题的答案在这里:
Apache Commons FTP storeFileStream返回空


顺便说一句,我确信文档是错误的。当文件不存在时,可以调用FTPClient.storeFileStream

正如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(。

最新更新