java-ftp 上传、删除文件(支持中文目录、文件名)
一、问题
描述:Java中FTPClient上传中文目录、中文文件名乱码问题解决方法
原因:FTP协议里面,规定文件名编码为iso-8859-1,所以目录名或文件名需要转码。
解决方案:name=new String(name.getBytes("GBK"),"iso-8859-1"); 使用这个转码
二、ftp 上传代码
package me.grass.net;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPReply;
import me.grass.coder.Debug;
import me.grass.extend.StringExtend;
/**
*
* @author xxj
*/
public class FtpHelper implements Closeable {
private FTPClient ftpClient = null;
boolean _isLogin = false;
public static FtpHelper getInstance() {
return new FtpHelper();
}
/**
* 使用实例
* @param args
*/
public static void main(String[] args) {
FtpHelper ftp = FtpHelper.getInstance();
ftp.login("localhost", 21);
}
/**
*
* ftp 匿名登录
* @param ip ftp服务地址
* @param port 端口号
* @param uname 用户名
* @param pass 密码
*/
public boolean login(String ip,int port){
//如果没有设置ftp用户可将username设为anonymous,密码为任意字符串
return login(ip, port,"anonymous","");
}
/**
*
* ftp登录
* @param ip ftp服务地址
* @param port 端口号
* @param uname 用户名
* @param pass 密码
*/
public boolean login(String ip,int port, String uname, String pass) {
ftpClient = new FTPClient();
// boolean flag=false;
try {
// 连接
ftpClient.connect(ip,port);
_isLogin = ftpClient.login(uname, pass);
Debug.printFormat("ftp:{0}",_isLogin?"登录成功":"登录失败");
// 检测连接是否成功
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
System.err.println("FTP服务器拒绝连接 ");
return false;
}
return true;
} catch (Exception ex) {
ex.printStackTrace();
return false;
}
}
/**
*
* ftp上传文件
* @param localFileName 待上传文件
* @param ftpDirName ftp 目录名
* @param ftpFileName ftp目标文件
* @return true||false
*/
public boolean uploadFile(String localFileName,String ftpDirName, String ftpFileName) {
Debug.printFormat("准备上传 [{0}] 到 ftp://{1}{2}"
,localFileName
,ftpDirName
,ftpFileName);
if(StringExtend.isNullOrEmpty(ftpDirName))
ftpDirName="/";
if(StringExtend.isNullOrEmpty(ftpFileName))
throw new RuntimeException("上传文件必须填写文件名!");
//解决中文目录、文件名乱码问题
try {
ftpDirName = new String(ftpDirName.getBytes("GBK"),"iso-8859-1");
ftpFileName = new String(ftpFileName.getBytes("GBK"),"iso-8859-1");
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
throw new RuntimeException(e1.getMessage(), e1);
}
File srcFile = new File(localFileName);
if(!srcFile.exists())
throw new RuntimeException("文件不存在:"+localFileName);
try (FileInputStream fis = new FileInputStream(srcFile)) {
// 设置上传目录
ftpClient.changeWorkingDirectory(ftpDirName);
ftpClient.setBufferSize(1024);
//解决上传中文 txt 文件乱码
ftpClient.setControlEncoding("GBK");
FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);
conf.setServerLanguageCode("zh");
// 设置文件类型(二进制)
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
// 上传
if(ftpClient.storeFile(ftpFileName, fis)){
fis.close();
Debug.printFormat("文件上传成功:{0}{1}"
,ftpDirName
,ftpFileName);
return true;
}
return false;
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
}
}
/**
*
* 删除ftp上的文件
*
* @param ftpFileName
* @return true || false
*/
public boolean removeFile(String ftpFileName) {
boolean flag = false;
Debug.printFormat("待删除文件:{0}"
,ftpFileName);
try {
ftpFileName = new String(ftpFileName.getBytes("GBK"),"iso-8859-1");
flag = ftpClient.deleteFile(ftpFileName);
Debug.printFormat("删除文件:[{0}]"
,flag?"成功":"失败");
return flag;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
/**
*
* 销毁ftp连接
*
*/
private void closeFtpConnection() {
_isLogin = false;
if (ftpClient != null) {
if (ftpClient.isConnected()) {
try {
ftpClient.logout();
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
*
* 销毁ftp连接
*
*/
@Override
public void close() {
this.closeFtpConnection();
}
}
三、测试方法
package me.grass.extend;
import static org.junit.Assert.*;
import javax.print.attribute.standard.Finishings;
import org.apache.taglibs.standard.lang.jstl.test.beans.PublicInterface2;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import me.grass.net.FtpHelper;
/**
*
* @author xxj
*/
public class FtpHelperTest {
FtpHelper ftp=null;
@Before
public void InitBinder(){
ftp = FtpHelper.getInstance();
ftp.login("localhost", 21);//匿名登录
}
@After
public void finish(){
ftp.close();
}
@Test
public void testUplodaFile() {
String localFile="D:/Temp/resource/img.jpg";
String ftpDir="temp";
String ftpFile=StringExtend.format("img-{0}.jpg"
, DateExtend.getDate("yyyyMMddHHmmss"));
boolean success = ftp.uploadFile(localFile,ftpDir, ftpFile);
assertTrue(success);
localFile="D:/Temp/resource/text.txt";
ftpDir="temp";
ftpFile=StringExtend.format("text-{0}.txt"
, DateExtend.getDate("yyyyMMddHHmmss"));
success = ftp.uploadFile(localFile,ftpDir, ftpFile);
assertTrue(success);
localFile="D:/Temp/resource/文本.txt";
ftpDir="temp";
ftpFile=StringExtend.format("文本-{0}.txt"
, DateExtend.getDate("yyyyMMddHHmmss"));
success = ftp.uploadFile(localFile,ftpDir, ftpFile);
assertTrue(success);
}
@Test
public void testRemove(){
boolean success = false;
String file ="/temp/文本-20170509175507.txt";
success = ftp.removeFile(file);
assertTrue(success);
}
}