我的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.
[正如MartinPrikryl在评论中已经提到的,不要叫InputStream is = new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8));
ftpClient.storeFile(filename, is);
,这是enterRemotePassiveMode
每次都是OutputStream os
的原因。
我为解决此问题所做的操作(创建但未写入文件):
null
。BufferedReader
看起来还不错,但是值得在发送之前检查它是否还好。这是因为在Android Studio中进行大量构建(我在其他IDE中也经历过)可以使变量“卡住”其旧值,可以通过清理项目和/或重新启动Android Studio来修复变量。]工作代码:
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
)替换。