直接贴代码:
import .ftp.FTPClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.ponent;
import java.io.*;
/**
* FTP工具类
*/
@Component
public class FtpUtil {
/**
* 注入连接池对象
*/
@Autowired
private FTPClientPool ftpClientPool;
/**
* Description: 获取FTP文件流
* filePath格式 /xxx/xxx
*/
public byte[] getFileSteam(String filePath, String ftpName) throws Exception {
InputStream in = null;
byte[] bytes = null ;
FTPClient ftpClient = getFtpClient();
try {
// 使用相对路径
filePath = filePath.substring(1);
// 切换FTP目录
boolean change = ftpClient.changeWorkingDirectory(new String((filePath).getBytes("utf-8"), "iso-8859-1"));
if (change) {
in = ftpClient.retrieveFileStream(new String(ftpName.getBytes("utf-8"), "iso-8859-1"));
bytes = readStream(in);
} else {
throw new RuntimeException("获取文件输入流失败----原因----切换工作目录失败");
}
} catch (Exception e) {
throw new RuntimeException("获取文件输入流失败");
} finally {
ftpClientPool.returnObject(ftpClient);
in.close();
}
return bytes;
}
/**
* 输入流转输出流
*/
public static byte[] readStream(InputStream inStream) throws Exception {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = -1;
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
outStream.close();
inStream.close();
return outStream.toByteArray();
}
/**
* 从连接池获取对象
*/
public FTPClient getFtpClient() throws Exception {
return ftpClientPool.borrowObject();
}
}
import .ftp.FTPClient;
import mons.pool.ObjectPool;
import mons.pool.PoolableObjectFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.ponent;
import java.io.IOException;
import java.util.NoSuchElementException;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* FTP连接池
*/
@Component
public class FTPClientPool implements ObjectPool, InitializingBean {
/**
* FTP连接池默认大小
*/
private static final int DEFAULT_POOL_SIZE = 5;
private final BlockingQueue pool;
@Autowired
private FtpClientFactory factory;
public FTPClientPool() throws Exception {
this.pool = new ArrayBlockingQueue(DEFAULT_POOL_SIZE);;
}
public void initPool() throws Exception {
for(int i = 0 ; i < DEFAULT_POOL_SIZE ; i ++){
addObject();
}
}
@Override
public FTPClient borrowObject() throws Exception, NoSuchElementException, IllegalStateException {
// 从连接池拿出一个连接,连接池中连接对象减一
FTPClient client = pool.take();
if (client == null) {
throw new RuntimeException("从连接池获取连接失败!");
}
return client;
}
@Override
public void returnObject(FTPClient obj) throws Exception {
if (obj != null) {
try {
// 归还连接
factory.passivateObject(obj);
// 将连接还给队列
pool.offer(obj);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 移除无效的客户端
* @param obj
* @throws Exception
*/
@Override
public void invalidateObject(FTPClient obj) throws Exception {
pool.remove(obj);
}
@Override
public void addObject() throws Exception, IllegalStateException, UnsupportedOperationException {
this.pool.offer(factory.makeObject());
}
@Override
public int getNumIdle() throws UnsupportedOperationException {
return 0;
}
@Override
public int getNumActive() throws UnsupportedOperationException {
return 0;
}
@Override
public void clear() throws Exception, UnsupportedOperationException {
pool.clear();
}
@Override
public void close() throws Exception {
while(pool.iterator().hasNext()){
FTPClient client = pool.take();
factory.destroyObject(client);
}
}
@Override
public void setFactory(PoolableObjectFactory factory) throws IllegalStateException, UnsupportedOperationException {
}
/**
* 连接池对象销毁前关闭连接
*/
@Override
protected void finalize() throws Throwable {
super.finalize();
close();
}
@Override
public void afterPropertiesSet() throws Exception {
initPool();
}
}
import .ftp.FTP;
import .ftp.FTPClient;
import .ftp.FTPReply;
import mons.pool.PoolableObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.ponent;
import java.io.IOException;
@Component
public class FtpClientFactory implements PoolableObjectFactory {
@Autowired
private FTPConfig ftpConfig;
@Override
public FTPClient makeObject() throws Exception {
FTPClient ftpClient = new FTPClient();
ftpClient.setConnectTimeout(1000);
try {
ftpClient.connect(ftpConfig.getIp(), ftpConfig.getPort());
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
throw new RuntimeException("ftpClient连接失败!");
}
boolean result = ftpClient.login(ftpConfig.getUsername(), ftpConfig.getPassword());
if (!result) {
throw new RuntimeException("ftpClient登陆失败!");
}
if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK).
ftpClient.setControlEncoding("UTF-8");
}
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.setBufferSize(1024);
ftpClient.enterLocalPassiveMode(); //ftp被动连接模式
reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
throw new RuntimeException("ftpClient连接失败!");
}
} catch (IOException e) {
ftpClient.disconnect();
e.printStackTrace();
} catch (Exception e) {
ftpClient.disconnect();
e.printStackTrace();
}
return ftpClient;
}
/**
* 关闭连接
* @param obj
* @throws Exception
*/
@Override
public void destroyObject(FTPClient obj) throws Exception {
try {
if (obj != null && obj.isConnected()) {
obj.logout();
}
} catch (IOException io) {
io.printStackTrace();
} finally {
// 注意,一定要在finally代码中断开连接,否则会导致占用ftp连接情况
try {
obj.disconnect();
} catch (IOException io) {
io.printStackTrace();
}
}
}
@Override
public boolean validateObject(FTPClient obj) {
try {
return obj.sendNoOp();
} catch (IOException e) {
throw new RuntimeException("Failed to validate client: " + e, e);
}
}
@Override
public void activateObject(FTPClient obj) throws Exception {
}
/**
* 归还连接
* @param obj
* @throws Exception
*/
@Override
public void passivateObject(FTPClient obj) throws Exception {
try {
if (obj != null && obj.isConnected()) {
pletePendingCommand();
obj.changeWorkingDirectory("/");
}
} catch (IOException io) {
io.printStackTrace();
}
}
}
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.ponent;
@Component
@PropertySource("classpath:application-ftp.yml")
@ConfigurationProperties(prefix = "ftp")
@Data
public class FTPConfig {
private String ip;
private int port;
private String username;
private String password;
}
以上就是FTPClient连接池全部实现。
但是有个问题,测试环境用的是XLight FTP Server,用同一个账号连接,最多只能同时连5个,希望知道的大佬告知怎么设置。