ftp工具类所需maven配置如下
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.4</version>
</dependency>
使用ThreadLocal(线程本地变量)获取的ftp客服端的方式实现的ftp的多线程下载,以下工具类仅供参考
package common.utils;
import java.io.*;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Properties;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import common.PropertiesFileUtil;
import dto.Ftp;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.log4j.Logger;
/**
* ftp文件服务
*/
public class FtpUtil {
private Logger logger=Logger.getLogger(FtpUtil.class);
private static FTPClient ftp;
private ThreadLocal<FTPClient> ftpClientThreadLocal = new ThreadLocal<FTPClient>(); //线程局部变量
private static class FTPUtilInstance {
private static FtpUtil ftpUtil = new FtpUtil();
}
public static FtpUtil getInstance() {
return FTPUtilInstance.ftpUtil;
}
/**
* 获取ftp连接
* @param f
* @return
* @throws Exception
*/
public boolean connectFtp(Ftp f) throws Exception{
ftp=new FTPClient();
boolean flag=false;
int reply;
if (f.getPort()==null) {
ftp.connect(f.getIpAddr(),21);
}else{
ftp.connect(f.getIpAddr(),f.getPort());
}
ftp.login(f.getUserName(), f.getPwd());
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
return flag;
}
/* ftp.setDataTimeout(60000); //设置传输超时时间为60秒
ftp.setConnectTimeout(60000);*/
ftp.changeWorkingDirectory("/");
flag = true;
return flag;
}
/**
* 关闭ftp连接
*/
public void closeFtp(){
if (ftp!=null && ftp.isConnected()) {
try {
ftp.logout();
ftp.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 获取ftp连接(多线程)
* @return
* @throws Exception
*/
public FTPClient getFTPClient() throws Exception{
if (ftpClientThreadLocal.get() != null && ftpClientThreadLocal.get().isConnected()) {
return ftpClientThreadLocal.get();
}
Ftp f = getFtp();
FTPClient ftpClient=new FTPClient();
boolean flag=false;
int reply;
if (f.getPort()==null) {
ftpClient.connect(f.getIpAddr(),21);
}else{
ftpClient.connect(f.getIpAddr(),f.getPort());
}
ftpClient.login(f.getUserName(), f.getPwd());
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
return ftpClient;
}
ftpClient.changeWorkingDirectory("/");
ftpClientThreadLocal.set(ftpClient);
return ftpClient;
}
/**
* 断开ftp连接(多线程)
*
* @throws Exception
*/
public void disconnect() throws Exception {
try {
FTPClient ftpClient = getFTPClient();
ftpClient.logout();
if (ftpClient.isConnected()) {
ftpClient.disconnect();
ftpClient = null;
}
} catch (IOException e) {
throw new Exception("Could not disconnect from server.", e);
}
}
/**
* 获取ftp链接常量
* @return
*/
public Ftp getFtp(){
Ftp f=new Ftp();
Properties properties = PropertiesFileUtil.getProperties("properties/ftp.properties");
f.setIpAddr(properties.getProperty("ftp.ipAddr"));
f.setUserName(properties.getProperty("ftp.userName"));
f.setPwd(properties.getProperty("ftp.pwd"));
f.setPort(Integer.parseInt(properties.getProperty("ftp.port")));
f.setSysFile(properties.getProperty("ftp.sysFile"));
f.setHeadImgFile(properties.getProperty("ftp.headimage"));
f.setIdApprRead(properties.getProperty("ftp.ipAddrRead"));
f.setUserNameRead(properties.getProperty("ftp.userNameRead"));
f.setPwdRead(properties.getProperty("ftp.pwdRead"));
return f;
}
/**
* InputStream-->byte[]
* @throws IOException
*/
public byte[] readInputStream(InputStream inputStream) throws Exception{
byte[] buffer = new byte[1024];
int len = -1;
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
while((len = inputStream.read(buffer)) != -1){
outputStream.write(buffer, 0, len);
}
outputStream.close();
inputStream.close();
return outputStream.toByteArray();
}
/*
* 下载获得文件的二进制流信息
* @param key
* @return
* @throws java.io.IOException
*/
public byte[] download(String key) throws Exception {
return download(key, null);
}
/**
* 多线程下载
* @param key
* @param type
* @return
*/
public byte[] download(String key,String type) {
byte[] objFile=null;
Ftp f = getFtp();
String cacheFile = "/cache_"+key;
if(null == type){
//设置目录
key=f.getSysFile()+key;
}else{
//设置目录
key=f.getHeadImgFile()+key;
}
FTPClient ftpClient = null;
try {
ftpClient = getFTPClient();
if (ftpClient!=null && ftpClient.isConnected()) {
try {
ftpClient.changeWorkingDirectory("/");
File localFile = new File(cacheFile);
if(localFile.exists()){
localFile.createNewFile();//创建文件
}
OutputStream outputStream = new FileOutputStream(localFile);
ftpClient.enterLocalPassiveMode();
ftpClient.setUseEPSVwithIPv4(true);
// ftp.retrieveFile("1.jpg", outputStream);
ftpClient.retrieveFile(key, outputStream);
InputStream inputStream = new FileInputStream(localFile);
objFile = readInputStream(inputStream);
outputStream.close();
inputStream.close();
localFile.delete();
} catch (Exception e) {
logger.error(e);
logger.error("下载过程中出现异常");
}
}else{
logger.error("链接失败!");
}
}catch (Exception e){
e.printStackTrace();
}finally {
try{
disconnect();
}catch (Exception e){
e.printStackTrace();
}
}
return objFile;
}
/**
* 上传文件
* @param key 实为文件名,可以为:upload/20150306/text.txt
* @param input 文件流
* @return
*/
public String upload(String key, InputStream input){
return upload(key, input, null);
}
/**
* 多线程上传
* @param key
* @param input
* @param type
* @return
*/
public String upload(String key, InputStream input, String type) {
String etag="";
Ftp f = getFtp();
if(null == type){
//设置目录
key=f.getSysFile()+key;
}else{
//设置目录
key=f.getHeadImgFile()+key;
}
FTPClient ftpClient = null;
try {
ftpClient = getFTPClient();
if (ftpClient!=null && ftpClient.isConnected()) {
ftpClient.enterLocalPassiveMode();
ftpClient.setUseEPSVwithIPv4(true);
ftpClient.storeFile(key,input);
input.close();
etag="succ";
}
}catch (Exception e){
e.printStackTrace();
throw new RuntimeException("FTP客户端出错!", e);
}finally {
try{
disconnect();
}catch (Exception e){
e.printStackTrace();
}
}
return etag;
}
/**
* 删除一个存储在FTP服务器上的文件
* @param key
*/
public void delete(String key){
Ftp f = getFtp();
key=f.getSysFile()+key;
try{
if (connectFtp(f)) {
ftp.deleteFile(key);
}
}catch (Exception e){
e.printStackTrace();
}finally {
closeFtp();
}
}
/**
* 多线程下载
* @param fileName
* @return
*/
public Object[] getDownLoadStream(String fileName){
Long dataLength = null;
byte[] objFile=null;
Ftp f = getFtp();
fileName=f.getSysFile()+fileName;
FTPClient ftpClient = null;
try {
ftpClient = getFTPClient();
if (ftpClient!=null && ftpClient.isConnected()) {
File localFile = new File("/cache_"+fileName);
if(localFile.exists()){
localFile.createNewFile();//创建文件
}
OutputStream outputStream = new FileOutputStream(localFile);
ftpClient.enterLocalPassiveMode();
ftpClient.setUseEPSVwithIPv4(true);
// ftp.retrieveFile("1.jpg", outputStream);
ftpClient.retrieveFile(fileName, outputStream);
InputStream inputStream = new FileInputStream(localFile);
objFile = readInputStream(inputStream);
dataLength = (long)inputStream.available();
outputStream.close();
inputStream.close();
localFile.delete();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try{
disconnect();
}catch (Exception e){
e.printStackTrace();
}
}
Object[] res = new Object[]{objFile,dataLength};
return res;
}
/**
* 获取Ftp下载路径
* @param key
* @return
*/
public String getObjectUrl(String key){
Ftp f = getFtp();
key=f.getSysFile()+key;
String alpath = "ftp://"+f.getUserNameRead()+":"+f.getPwdRead()+"@"+f.getIdApprRead()+":"+f.getPort() + key;
return alpath;
}
}
#FTP配置信息
#ip地址 本地:172.16.230.161
ftp.ipAddr=172.16.230.161
#用户名
ftp.userName=ftp
#密码
ftp.pwd=123456
#端口号 ftp默认21
ftp.port=21
#命名名空间下使用的文件夹
ftp.sysFile=/KsrzSysFile/
ftp.headImgFile=/headimage/
#ip地址 本地:172.16.230.161
ftp.ipAddrRead=172.16.230.161
#用户名
ftp.userNameRead=ftpread
#密码
ftp.pwdRead=123456
ftp常量类 仅供参考
package dto;
/**
* ftp链接常量
*/
public class Ftp {
private String ipAddr;//ip地址
private Integer port;//端口号
private String userName;//用户名
private String pwd;//密码
private String path;//aaa路径
private String sysFile;//项目中内容所要上传的文件夹地址
private String headImgFile;//用户头像文件夹地址
private String idApprRead;//只读ip地址
private String userNameRead;//只读用户名
private String pwdRead;//只读密码
public String getIpAddr() {
return ipAddr;
}
public void setIpAddr(String ipAddr) {
this.ipAddr = ipAddr;
}
public Integer getPort() {
return port;
}
public void setPort(Integer port) {
this.port = port;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getSysFile() {
return sysFile;
}
public void setSysFile(String sysFile) {
this.sysFile = sysFile;
}
public String getHeadImgFile() {
return headImgFile;
}
public void setHeadImgFile(String headImgFile) {
this.headImgFile = headImgFile;
}
public String getIdApprRead() {
return idApprRead;
}
public void setIdApprRead(String idApprRead) {
this.idApprRead = idApprRead;
}
public String getUserNameRead() {
return userNameRead;
}
public void setUserNameRead(String userNameRead) {
this.userNameRead = userNameRead;
}
public String getPwdRead() {
return pwdRead;
}
public void setPwdRead(String pwdRead) {
this.pwdRead = pwdRead;
}
}