如果没有没有中文路径,则获取文件或者获取文件流都是比较简单的。网上有大把的例子,拿来改薄该博就可以了。但一出现中文路径,则难度增加不少。关键是要知道你公司的ftp服务器默认的编码格式。这个很重要!
一般默认ftp服务器是GBK编码格式的。好,先认识一下几个常见的编码,今天都要用。
1. GBK
2. ISO-8859-1
3. UTF-8
我们一般登录到FTP服务器上时,所在的目录就是根目录,当然,如果不是也没太大关系,只要知道根目录到指定要进入的目录路径就能切到指定目录上。比如:String path="/records/sxks/凯森022/20171001/2023249/2023249-01.mp3";
这是我们要找的录音文件全路径。但是我们等进来进的目录不知道是那层,这都无所谓,直接用这个路径就能找到我们的文件。但是这里问题就在路径有中文,如何让路径编码正确?这里可以通过用方法:ftpClient.changeWorkingDirectory(path)
来看返回的boolean值判断切换目录成功没有来确认。true表示成功。
1.拆分路径
为/records/sxks/凯森022/
和/20171001/2023249/2023249-01.mp3
,只要第一个路径切换成功,表示编码方式对,就可以找到全路径下的文件了。(当然还有别的拆分方式/records/sxks/凯森022/20171001/2023249/
+2023249-01.mp3
等等)
2.对路径进行编码处理后测试切换。
由于老路径String oldPath="/records/sxks/凯森022/";
2.1 对路径进行GBK->ISO
编码,用上面的方法尝试。我就是用这种方式才能正常切换到中文目录下的。
String newPath1=new String(oldPath.getBytes("GBK"),"ISO-8859-1");
boolean flag=ftpClient.changeWorkingDirectory(newPaths);
2.2 对路径进行GBK->UTF-8
编码,用上面的方法尝试。我就是用这种方式才能正常切换到中文目录下的。
String newPath1=new String(oldPath.getBytes("GBK"),"UTF-8");
boolean flag=ftpClient.changeWorkingDirectory(newPaths);
2.3 还可以通过下面的方法判断ftp服务器是不是支持UTF-8这种编码方式
private String LOCAL_CHARSET="GBK";
if(FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF-8","ON"))){
LOCAL_CHARSET="UTF-8";
}
- 具体代码如下
package com.zhanglf.utils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import com.zhanglf.dto.entity.FTPConfigBo;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class FTPUtil {
public static String LOCAL_CHARSET="GBK";
public static String DEFAULT_CHARSET="iso-8859-1";
/** * 获取FTPClient对象 * @param host FTP对应的IP地址 * @param port FTP端口 * @param username FTP用户名 * @param password FTP用户密码 * @return */
public static FTPClient getFTPClient(FTPConfigBo ftpConfig){
FTPClient ftpClient=new FTPClient();
try {
ftpClient=new FTPClient();
//如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
//ftpClient.connect(host, port);
ftpClient.connect(ftpConfig.getHost());
if(FTPReply.isPositiveCompletion(ftpClient.getReplyCode())){
if(ftpClient.login(ftpConfig.getUsername(), ftpConfig.getPassword())){
log.info("FTP连接成功!");
ftpClient.setControlEncoding(LOCAL_CHARSET);//中文支持
ftpClient.enterLocalPassiveMode();//设置被动模式
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);//设置传输模式
//开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK).
if(FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF-8","ON"))){
LOCAL_CHARSET="UTF-8";
}
}
}else{
log.info("未连接到FTP,用户名或者密码错误。");
ftpClient.disconnect();
}
} catch (Exception e) {
log.error("FTP获取ftp客户端对象异常,异常信息为: "+e.getMessage(),e);
}
return ftpClient;
}
public static byte[] input2byte(InputStream in) throws IOException{
ByteArrayOutputStream swapStream =new ByteArrayOutputStream();
byte[] buff=new byte[in.available()];
int rc=0;
while((rc = in.read(buff,0,100)) > 0){
swapStream.write(buff,0,rc);
}
byte[] in2b=swapStream.toByteArray();
swapStream.close();
return in2b;
}
/** * 根据ftp文件路径和ftp连接获取该文件对应的流信息 * @param path 文件在ftp的路径,比如:/records/sxks/ /凯森1W4/20171211/20367962/ + 20367962-01.mp3 * @param ftpClient * @return * @throws Exception */
public static InputStream getInputStreamFromFtp(String pathName,FTPClient ftpClient) throws Exception{
String[] pathArray = pathName.split("/");
String filename=pathArray[pathArray.length-1]; //获取录音文件名:20300981-01.mp3
String contno=pathArray[pathArray.length-2]; //获取保单号:20300981
String ymd=pathArray[pathArray.length-3]; //获取年月日:20171211
String code=pathArray[pathArray.length-4]; //获取外包机构码:凯森1W4
String wbcode=pathArray[pathArray.length-5]; //获取外包商登录名:shzh,sxks等等
String dic=code+"/"+ymd+"/"+contno+"/";
//防止中文编码导致目录找不到
String directory = new String(dic.getBytes(FTPUtil.LOCAL_CHARSET),FTPUtil.DEFAULT_CHARSET);
//更换目录到当前目录
ftpClient.changeWorkingDirectory(directory);
ftpClient.setBufferSize(1024);
return ftpClient.retrieveFileStream(filename);
}
}