这两天做了一个ftp文件上传和下载功能,开发中发现上传失败,没有将文件上传到服务器上面,下载的时候只是创建了一个文件,文件大小为0kb,两个ftp服务器互相传输也会出现种现象。这中现象都是因为编码格式导致的,也就是文件名中有中文,没有中文的时候应该都是正常的。
使用的环境:
工具IDEA,jdk1.8,
jar包有commons-net-3.8.0.jar、jakarta-oro-2.0.8.jar
1、上传时调用FTPClient的storeFile()方法没有成功上传文件到服务器。
有人说要先调用FTPClient的enterLocalPassiveMode()方法,试过之后还是不成功,后来看网上有人说文件名需要处理下,代码入下:
boolean b = ftpClient.storeFile(new String(file2.getName().getBytes("GB2312"),"ISO-8859-1"), inputStream);
调用上面方法后,文件上传成功。
原因还没有研究,只是这样调用之后就上传成功了。
2、调用FTPClient的retrieveFile()方法,这时下载了一个大小为0kb的文件。
也是讲文件名做过处理之后就下载成功了,代码如下:
ftpClient.retrieveFile(new String(ftpFile.getName().getBytes("GB2312"),"ISO-8859-1"), outputStream);
3、一个ftp服务器通过Java向另外一个ftp服务器传送文件,出现上传0kb文件问题。
这个也是由于编码问题引起的(文件名中有中文),话不多说上代码:
/**
*
* @param ftpUp 上传ftp连接
* @param ftpDown 源文件ftp连接
*/
public void twoFTPTransfer(FTPClient ftpUp, FTPClient ftpDown){
try {
//先设置源文件的编码格式
ftpDown.setControlEncoding("GBK");
FTPFile[] ftpFiles = ftpDown.listFiles();
for (FTPFile ftpFile : ftpFiles){
//获取上传文件流
OutputStream outputStream = ftpUp.storeFileStream(new String(ftpFile.getName().getBytes("GB2312"), FTP.DEFAULT_CONTROL_ENCODING));
//这句话是把文件从ftpDown复制到ftpUp中,通过流outputStream
boolean b = ftpDown.retrieveFile(new String(ftpFile.getName().getBytes("GB2312"), FTP.DEFAULT_CONTROL_ENCODING), outputStream);
outputStream.close();
ftpUp.completePendingCommand();
System.out.println("ftpFile:" + ftpFile);
System.out.println("ftpFile.getName():" + ftpFile.getName());
System.out.println(new String(ftpFile.getName().getBytes("GB2312"), FTP.DEFAULT_CONTROL_ENCODING));
}
} catch (Exception e) {
logger.error("ftp传输失败:" + e);
}
}
上面的代码里面的 ftpDown.setControlEncoding("GBK"); 这句不要忘记写了,获取输出流或者写文件的时候会有问题。
下面是我获取ftp连接的代码,为了方便对着看我也拿上来了
/**
* 获取ftp连接
* @param ftp
* @return
* @throws IOException
*/
public static FTPClient connectFtp(Ftp ftp) throws IOException {
FTPClient ftpClient = new FTPClient();
int reply;
if(ftp.getPort() == null){
ftpClient.connect(ftp.getIpAddr(), 21);
}else {
ftpClient.connect(ftp.getIpAddr(), ftp.getPort());
}
ftpClient.login(ftp.getUserName(), ftp.getPwd());
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)){
//关闭与FTP服务器的连接并将连接参数恢复为默认值。
ftpClient.disconnect();
return null;
}
//ftpClient.makeDirectory(pathname);
ftpClient.enterLocalPassiveMode();
//文件路径中有中文的时候需要将路径做处理
ftpClient.changeWorkingDirectory(ftp.getPath());
return ftpClient;
}