21/tcp FTP 文件传输协议
22/tcp SSH 安全登录、文件传送(SCP)和端口重定向
23/tcp Telnet 不安全的文本传送
25/tcp SMTP Simple Mail Transfer Protocol (E-mail)
69/udp TFTP Trivial File Transfer Protocol
79/tcp finger Finger
80/tcp HTTP 超文本传送协议 (WWW)
88/tcp Kerberos Authenticating agent
110/tcp POP3 Post Office Protocol (E-mail)
113/tcp ident old identification server system
119/tcp NNTP used for usenet newsgroups
220/tcp IMAP3
443/tcp HTTPS used for securely transferring web pages
pom添加依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>1.6</version>
</dependency>
public class FTPTemplate {
public static FTPClientPool ftpClientPool;
public static FTPClient ftpClient; ##查看客户端
public static FTPClient writeftpClient; ## 上传客户端
public FTPTemplate(FTPProperties ftpProperties) {
FTPClientFactory factory = new FTPClientFactory(ftpProperties);
try {
ftpClientPool = new FTPClientPool(factory);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取连接对象
*
* @return
* @throws Exception
*/
public static FTPClient getFTPClient() throws Exception { //初始化的时候从队列中取出一个连接
if (ftpClient == null) {
synchronized (ftpClientPool) {
ftpClient = ftpClientPool.borrowObject();
}
}
return ftpClient;
}
/**
* 获取连接对象
*
* @return
* @throws Exception
*/
public static FTPClient getWriteFTPClient() throws Exception { //初始化的时候从队列中取出一个连接
if (writeftpClient == null) {
synchronized (ftpClientPool) {
writeftpClient = ftpClientPool.borrowObject();
}
}
return writeftpClient;
}
/**
* 当前命令执行完成命令完成
*
* @throws IOException
*/
public void complete() throws IOException {
ftpClient.completePendingCommand();
}
/**
* 当前线程任务处理完成,加入到队列的最后
*
* @return
*/
public void disconnect() throws Exception {
ftpClientPool.addObject(ftpClient);
}
/**
* Description: 向FTP服务器上传文件
*
* @param remoteFile 上传到FTP服务器上的文件名
* @param input 本地文件流
* @return 成功返回true,否则返回false
* @Version1.0
*/
public static boolean uploadFile(String remoteFile, InputStream input) {
boolean result = false;
try {
getWriteFTPClient();
writeftpClient.enterLocalPassiveMode();
result = writeftpClient.storeFile(remoteFile, input);
input.close();
writeftpClient.disconnect();
writeftpClient = null;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* Description: 向FTP服务器上传文件
*
* @param remoteFile 上传到FTP服务器上的文件名
* @param localFile 本地文件
* @return 成功返回true,否则返回false
* @Version1.0
*/
public static boolean uploadFile(String remoteFile, String localFile) {
FileInputStream input = null;
try {
input = new FileInputStream(new File(localFile));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return uploadFile(remoteFile, input);
}
/**
* 拷贝文件
*
* @param fromFile
* @param toFile
* @return
* @throws Exception
*/
public boolean copyFile(String fromFile, String toFile) throws Exception {
InputStream in = getFileInputStream(fromFile);
getFTPClient();
boolean flag = ftpClient.storeFile(toFile, in);
in.close();
return flag;
}
/**
* 获取文件输入流
*
* @param fileName
* @return
* @throws IOException
*/
public static InputStream getFileInputStream(String fileName) throws Exception {
ByteArrayOutputStream fos = new ByteArrayOutputStream();
getFTPClient();
ftpClient.retrieveFile(fileName, fos);
ByteArrayInputStream in = new ByteArrayInputStream(fos.toByteArray());
fos.close();
return in;
}
/**
* Description: 从FTP服务器下载文件
*
* @return
* @Version1.0
*/
public static boolean downFile(String remoteFile, String localFile) {
boolean result = false;
try {
getFTPClient();
OutputStream os = new FileOutputStream(localFile);
ftpClient.retrieveFile(remoteFile, os);
ftpClient.logout();
ftpClient.disconnect();
ftpClient = null;
result = true;
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
} catch (Exception e) {
e.printStackTrace();
}
}
return result;
}
/**
* 从ftp中获取文件流
*
* @param filePath
* @return
* @throws Exception
*/
public static InputStream getInputStream(String filePath) throws Exception {
getFTPClient();
InputStream inputStream = ftpClient.retrieveFileStream(filePath);
return inputStream;
}
/**
* ftp中文件重命名
*
* @param fromFile
* @param toFile
* @return
* @throws Exception
*/
public boolean rename(String fromFile, String toFile) throws Exception {
getFTPClient();
boolean result = ftpClient.rename(fromFile, toFile);
return result;
}
/**
* 获取ftp目录下的所有文件
*
* @param dir
* @return
*/
public FTPFile[] getFiles(String dir) throws Exception {
getFTPClient();
FTPFile[] files = new FTPFile[0];
try {
files = ftpClient.listFiles(dir);
} catch (Throwable thr) {
thr.printStackTrace();
}
return files;
}
/**
* 获取ftp目录下的某种类型的文件
*
* @param dir
* @param filter
* @return
*/
public FTPFile[] getFiles(String dir, FTPFileFilter filter) throws Exception {
getFTPClient();
FTPFile[] files = new FTPFile[0];
try {
files = ftpClient.listFiles(dir, filter);
} catch (Throwable thr) {
thr.printStackTrace();
}
return files;
}
/**
* 创建文件夹
*
* @param remoteDir
* @return 如果已经有这个文件夹返回false
*/
public boolean makeDirectory(String remoteDir) throws Exception {
getFTPClient();
boolean result = false;
try {
result = ftpClient.makeDirectory(remoteDir);
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
public boolean mkdirs(String dir) throws Exception {
boolean result = false;
if (null == dir) {
return result;
}
getFTPClient();
ftpClient.changeWorkingDirectory("/");
StringTokenizer dirs = new StringTokenizer(dir, "/");
String temp = null;
while (dirs.hasMoreElements()) {
temp = dirs.nextElement().toString(); //创建目录
ftpClient.makeDirectory(temp); //进入目录
ftpClient.changeWorkingDirectory(temp);
result = true;
}
ftpClient.changeWorkingDirectory("/");
return result;
}
}
public class FTPClientPool implements ObjectPool<FTPClient> {
private static final int DEFAULT_POOL_SIZE = 10;
public BlockingQueue<FTPClient> blockingQueue;
private FTPClientFactory factory;
public FTPClientPool(FTPClientFactory factory) throws Exception {
this(DEFAULT_POOL_SIZE, factory);
}
public FTPClientPool(int poolSize, FTPClientFactory factory) throws Exception {
this.factory = factory;
this.blockingQueue = new ArrayBlockingQueue<FTPClient>(poolSize);
initPool(poolSize);
}
/**
* 初始化连接池
*
* @param maxPoolSize 最大连接数
* @throws Exception
*/
private void initPool(int maxPoolSize) throws Exception {
int count = 0;
while (count < maxPoolSize) {
this.addObject();
count++;
}
}
/**
* 从连接池中获取对象
*/
@Override
public FTPClient borrowObject() throws Exception {
FTPClient client = blockingQueue.take();
if (client == null) {
client = factory.makeObject();
} else if (!factory.validateObject(client)) {
invalidateObject(client);
client = factory.makeObject();
}
return client;
}
/**
* 返还一个对象(链接)
*/
@Override
public void returnObject(FTPClient client) throws Exception {
if ((client != null) && !blockingQueue.offer(client, 2, TimeUnit.MINUTES)) {
try {
factory.destroyObject(client);
} catch (Exception e) {
throw e;
}
}
}
/**
* 移除无效的对象(FTP客户端)
*/
@Override
public void invalidateObject(FTPClient client) throws Exception {
blockingQueue.remove(client);
}
/**
* 增加一个新的链接,超时失效
*/
@Override
public void addObject() throws Exception {
blockingQueue.offer(factory.makeObject(), 2, TimeUnit.MINUTES);
}
/**
* 重新连接
*/
public FTPClient reconnect() throws Exception {
return factory.makeObject();
}
/**
* 获取空闲链接数(这里暂不实现)
*/
@Override
public int getNumIdle() {
return blockingQueue.size();
}
/**
* 获取正在被使用的链接数
*/
@Override
public int getNumActive() {
return DEFAULT_POOL_SIZE - getNumIdle();
}
@Override
public void clear() throws Exception {
}
/**
* 关闭连接池
*/
@Override
public void close() {
try {
while (blockingQueue.iterator().hasNext()) {
FTPClient client = blockingQueue.take();
factory.destroyObject(client);
}
} catch (Exception e) {
log.error("close ftp client pool failed...{}", e);
}
}
/**
* 增加一个新的链接,超时失效
*/
public void addObject(FTPClient ftpClient) throws Exception {
blockingQueue.put(ftpClient);
}
}
public class FTPClientFactory implements PoolableObjectFactory<FTPClient> {
private FTPProperties ftpProperties;
public FTPClientFactory(FTPProperties ftpProperties) {
this.ftpProperties = ftpProperties;
}
@Override
public FTPClient makeObject() throws Exception {
FTPClient ftpClient = new FTPClient();
ftpClient.setControlEncoding(ftpProperties.getEncoding());
ftpClient.setConnectTimeout(ftpProperties.getClientTimeout());
try {
ftpClient.connect(ftpProperties.getHost(), ftpProperties.getPort());
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
log.warn("FTPServer refused connection");
return null;
}
boolean result = ftpClient.login(ftpProperties.getUsername(), ftpProperties.getPassword());
ftpClient.setFileType(ftpProperties.getTransferFileType());
if (!result) {
log.warn("ftpClient login failed... username is {}", ftpProperties.getUsername());
}
} catch (Exception e) {
log.error("create ftp connection failed...{}", e);
throw e;
}
return ftpClient;
}
@Override
public void destroyObject(FTPClient ftpClient) throws Exception {
try {
if (ftpClient != null && ftpClient.isConnected()) {
ftpClient.logout();
}
} catch (Exception e) {
log.error("ftp client logout failed...{}", e);
throw e;
} finally {
if (ftpClient != null) {
ftpClient.disconnect();
}
}
}
@Override
public boolean validateObject(FTPClient ftpClient) {
try {
return ftpClient.sendNoOp();
} catch (Exception e) {
log.error("Failed to validate client: {}");
}
return false;
}
@Override
public void activateObject(FTPClient obj) throws Exception { //Do nothing
}
@Override
public void passivateObject(FTPClient obj) throws Exception { //Do nothing
}
}
注意:FtpClient可以实现同时上传和下载,只要FTPClient 不是同一个对象就可以