项目中用的ftp上传文件发现上传的很慢,
在网上找到了自定义的ftp连接池,感觉不错,以此记录一下!
如有侵权,联系我立即删除此贴
#文件服务器配置
spring.sftp.username=root
spring.sftp.passwd=root
spring.sftp.servert_type=sftp
spring.sftp.servert_port=22
spring.sftp.servert_ip=192.168.xx.xx
spring.sftp.servert_upload=/upload/
用到的工具类
package com.xxx.utils.ftp;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class ByteUtil {
public static byte[] inputStreamToByteArray(InputStream in) throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[1024*4];
int n = 0;
while (-1 != (n = in.read(buffer))) {
output.write(buffer, 0, n);
}
return output.toByteArray();
}
}
package com.xxx.utils.ftp;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
// ftp配置
@Configuration
@EnableConfigurationProperties(SftpProperties.class)
public class SftpConfig {
// 工厂
@Bean
public SftpFactory sftpFactory(SftpProperties properties) {
return new SftpFactory(properties);
}
// 连接池
@Bean
public SftpPool sftpPool(SftpFactory sftpFactory) {
return new SftpPool(sftpFactory);
}
// 辅助类
@Bean
public SftpHelper sftpHelper(SftpPool sftpPool) {
return new SftpHelper(sftpPool);
}
}
package com.xxx.utils.ftp;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import java.util.Properties;
@Slf4j
public class SftpFactory extends BasePooledObjectFactory<ChannelSftp> {
private SftpProperties properties;
public SftpFactory(SftpProperties properties) {
this.properties = properties;
}
public SftpProperties getProperties() {
return properties;
}
public void setProperties(SftpProperties properties) {
this.properties = properties;
}
@Override
public ChannelSftp create() throws JSchException {
try {
JSch jsch = new JSch();
Session sshSession = jsch.getSession(properties.getUsername(), properties.getServert_ip(), properties.getServert_port());
sshSession.setPassword(properties.getPasswd());
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();
ChannelSftp channel = (ChannelSftp) sshSession.openChannel("sftp");
channel.connect();
return channel;
} catch (JSchException e) {
// throw new ProjectException("连接sfpt失败", e);
throw e;
}
}
@Override
public PooledObject<ChannelSftp> wrap(ChannelSftp channelSftp) {
return new DefaultPooledObject<>(channelSftp);
}
// 销毁对象
@Override
public void destroyObject(PooledObject<ChannelSftp> p) {
ChannelSftp channelSftp = p.getObject();
channelSftp.disconnect();
}
}
package com.xxx.utils.ftp;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.SftpException;
import java.io.InputStream;
// sftp辅助类
public class SftpHelper {
private SftpPool pool;
public SftpHelper(SftpPool pool) {
this.pool = pool;
}
/**
* 下载文件
* @param dir 远程目录
* @param name 远程文件名
* @return 文件字节数组
*/
public byte[] download(String dir, String name) throws Exception {
ChannelSftp sftp = pool.borrowObject();
try {
sftp.cd(dir);
InputStream in = sftp.get(name);
return ByteUtil.inputStreamToByteArray(in);
} catch (SftpException e) {
// throw new ProjectException("sftp下载文件出错", e);
throw e;
} finally {
pool.returnObject(sftp);
}
}
/**
* 上传文件
* @param dir 远程目录
* @param name 远程文件名
* @param in 输入流
*/
public void upload(String dir, String name, InputStream in) throws Exception {
ChannelSftp sftp = pool.borrowObject();
try {
mkdirs(sftp, dir);
sftp.cd(dir);
sftp.put(in, name);
} catch (SftpException e) {
// throw new ProjectException("sftp上传文件出错", e);
throw e;
} finally {
pool.returnObject(sftp);
}
}
/**
* 删除文件
* @param dir 远程目录
* @param name 远程文件名
*/
public void delete(String dir, String name) throws Exception {
ChannelSftp sftp = pool.borrowObject();
try {
sftp.cd(dir);
sftp.rm(name);
} catch (SftpException e) {
// throw new ProjectException("sftp删除文件出错", e);
throw e;
} finally {
pool.returnObject(sftp);
}
}
/**
* 递归创建多级目录
* @param dir 多级目录
*/
private void mkdirs(ChannelSftp sftp, String dir) throws SftpException {
String[] folders = dir.split("/");
try {
sftp.cd("/");
for (String folder: folders) {
if (folder.length()>0) {
try {
sftp.cd(folder);
} catch (Exception e) {
sftp.mkdir(folder);
sftp.cd(folder);
}
}
}
} catch (SftpException e) {
// throw new ProjectException("sftp创建目录出错", e);
throw e;
}
}
}
package com.xxxx.utils.ftp;
import com.jcraft.jsch.ChannelSftp;
import org.apache.commons.pool2.impl.GenericObjectPool;
public class SftpPool {
private GenericObjectPool<ChannelSftp> pool;
public SftpPool(SftpFactory factory) {
this.pool = new GenericObjectPool<>(factory, factory.getProperties().getPool());
}
/**
* 获取一个sftp连接对象
* @return sftp连接对象
*/
public ChannelSftp borrowObject() throws Exception {
try {
return pool.borrowObject();
} catch (Exception e) {
// throw new ProjectException("获取ftp连接失败", e);
throw e;
}
}
public GenericObjectPool<ChannelSftp> getPool() {
return pool;
}
public void setPool(GenericObjectPool<ChannelSftp> pool) {
this.pool = pool;
}
/**
* 归还一个sftp连接对象
* @param channelSftp sftp连接对象
*/
public void returnObject(ChannelSftp channelSftp) {
if (channelSftp!=null) {
pool.returnObject(channelSftp);
}
}
}
package com.xxxx.utils.ftp;
import com.jcraft.jsch.ChannelSftp;
import lombok.Data;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "spring.sftp")
public class SftpProperties {
private String username;//用户名
private String passwd;//用户密码
private String servert_type;//文件服务器类型
private int servert_port;//文件服务器的端口号
private String servert_ip;//文件服务器的ip地址
private String servert_upload;//上传到文件服务器的那个目录
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
public String getServert_type() {
return servert_type;
}
public void setServert_type(String servert_type) {
this.servert_type = servert_type;
}
public int getServert_port() {
return servert_port;
}
public void setServert_port(int servert_port) {
this.servert_port = servert_port;
}
public String getServert_ip() {
return servert_ip;
}
public void setServert_ip(String servert_ip) {
this.servert_ip = servert_ip;
}
public String getServert_upload() {
return servert_upload;
}
public void setServert_upload(String servert_upload) {
this.servert_upload = servert_upload;
}
public Pool getPool() {
return pool;
}
public void setPool(Pool pool) {
this.pool = pool;
}
private Pool pool = new Pool();
public static class Pool extends GenericObjectPoolConfig<ChannelSftp> {
private int maxTotal = DEFAULT_MAX_TOTAL;
private int maxIdle = DEFAULT_MAX_IDLE;
private int minIdle = DEFAULT_MIN_IDLE;
public Pool() {
super();
}
@Override
public int getMaxTotal() {
return maxTotal;
}
@Override
public void setMaxTotal(int maxTotal) {
this.maxTotal = maxTotal;
}
@Override
public int getMaxIdle() {
return maxIdle;
}
@Override
public void setMaxIdle(int maxIdle) {
this.maxIdle = maxIdle;
}
@Override
public int getMinIdle() {
return minIdle;
}
@Override
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
}
}
类中所用的maven依赖请行百度