Java 使用 FTP 实现大文件上传下载
JSCH ——java实现SFTP
jsch-0.1.50.jar
- JSCH 是Java Secure Channel的缩写,JSCH是一个SSH2的纯java实现,你可以到http://www.jcraft.com/jsch/中下载到最新的JSCH的jar包,源码以及实例;
- JSCH支持三种文件传输的方式:
OVERWRITE 完全覆盖模式,这是JSCH的默认的文件传输模式,即目标文件存在则传输文件完全覆盖掉目标文件;
RESUME 恢复模式,即断点续传,当传输中断,下次传输时从上一次中断处开始;
APPEND 追加模式,若目标文件已经存在,则传输文件将在目标文件后追加; - 以下是JSCH的一些用法:
public class FtpUtil {
protected static Logger log = Logger.getLogger(DBHelper.class);
private static ChannelSftp sftp = null;
private static Session sshSession = null;
public static final String NO_FILE = "No such file";
public static Properties properties = new Properties();
//设置不用检查hostKey
//如果设置成“yes”,ssh就不会自动把计算机的密匙加入“$HOME/.ssh/known_hosts”文件,
//并且一旦计算机的密匙发生了变化,就拒绝连接。
static {
properties.put("StrictHostKeyChecking", "no");
}
/**
* 下载文件
* @param host FTP服务器地址
* @param port FTP服务器端口号
* @param username FTP登录帐号
* @param password FTP登录密码
* @param directory FTP服务器文件目录
* @param fileName FTP服务器上文件名称 如xxx.txt 或 xxx.txt.zip
* @param localPath 下载到本地的文件 如:D:/xxx.txt
*/
public static File downloadFile(String host, String port, String username, String password, String directory, String fileName, localPath){
log.info(">>>>>>>>FtpUtil-->downloadFile--ftp下载文件"+fileName+"开始>>>>>>>>>>>>>");
int portInt = Integer.parseInt(port);
sftp = connect(host, portInt, username, password);
OutputStream output = null;
File file = null;
try {
file = certTempEmptyile(localPath);
output = new FileOutputStream(file);
sftp.cd(directory);//进入FTP服务器文件目录
sftp.get(fileName, output);
//sftp.disconnect();
} catch (SftpException e) {
if (e.toString().equals(NO_FILE)) {
log.info(">>>>>>>>FtpUtil-->downloadFile--ftp下载文件失败" + directory +fileName+ "不存在>>>>>>>>>>>>>");
throw new Exception("FtpUtil-->downloadFile--ftp下载文件失败" + directory +fileName + "不存在");
}
e.printStackTrace();
throw new Exception("ftp目录或者文件异常,检查ftp目录和文件" + e.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new Exception("本地目录异常,请检查" + file.getPath() + e.getMessage());
} finally {
if (output != null){
try {
output.close();
} catch (IOException e) {
log.error("Close stream error");
throw new GoPayException("Close stream error");
}
}
disconnect();
}
log.info(">>>>>>>>FtpUtil-->downloadFile--ftp下载文件结束>>>>>>>>>>>>>");
return file;
}
public static ChannelSftp connect(String host, int port, String username, String password) throws GoPayException {
log.info(">>>>>>>>FtpUtil-->connect--ftp连接开始>>>>>>>>>>>>>");
log.info("ftp参数>>>>>>host=" + host + ">>>port=" + port + ">>>username=" + username);
JSch jsch = new JSch();// 创建JSch对象
try {
// 按照用户名,主机ip,端口获取一个Session对象
jsch.getSession(username, host, port);
sshSession = jsch.getSession(username, host, port);
log.info("ftp---Session created.");
// 设置密码
sshSession.setPassword(password);
//具体config中需要配置那些内容,请参照sshd服务器的配置文件/etc/ssh/sshd_config的配置
sshSession.setConfig(properties);// 为Session对象设置properties
sshSession.connect();//经由过程Session建树链接
log.info("ftp---Session connected.");
log.info("ftp---Opening Channel.");
sftp = (ChannelSftp) sshSession.openChannel("sftp");// 打开SFTP通道
channel.connect();// 建树SFTP通道的连接
log.info("ftp---Connected to " + host);
log.info(">>>>>>>>FtpUtil-->connect--ftp连接结束>>>>>>>>>>>>>");
} catch (JSchException e) {
e.printStackTrace();
throw new Exception("FtpUtil-->connect异常" + e.getMessage());
}
return sftp;
}
/**
* @param localFilePath 本地路径 如:D:/test/
*/
private synchronized static File certTempEmptyile(String localFilePath) {
FileUtil.mkDir(localFilePath);
String newFileName = System.currentTimeMillis() + ".txt";
String filePath = localFilePath + File.separator + newFileName;
File file = new File(filePath);
return file;
}
public static void mkDir(String path) {
File file = new File(path);
if (!file.exists()) {//如果目录不存在
file.mkdirs();
}
}
/**
* 上传文件
* @param host FTP服务器地址
* @param port FTP服务器端口号
* @param username FTP登录帐号
* @param password FTP登录密码
* @param directory FTP服务器文件目录
* @param uploadFilePath 要上传的文件 如:D:\\test\\xxx.txt
* @param fileName FTP服务器文件名称 如:xxx.txt ||xxx.txt.zip
*/
public static void uploadFile(String host, String port, String username, String password, String directory, String uploadFilePath, String fileName)
throws Exception {
log.info(">>>>>>>>FtpUtil-->uploadFile--ftp上传文件开始>>>>>>>>>>>>>");
int portInt = Integer.parseInt(port);
InputStream input = null;
sftp = connect(host, portInt, username, password);
try {
sftp.cd(directory);
} catch (SftpException e) {
try {
sftp.mkdir(directory);
sftp.cd(directory);
} catch (SftpException e1) {
throw new Exception("ftp创建文件路径失败,路径为" + directory);
}
}
File file = new File(uploadFilePath);
try {
input = new FileInputStream(file);
sftp.put(input, fileName);
} catch (FileNotFoundException e) {
throw new Exception("文件不存在-->" + uploadFilePath);
} catch (SftpException e) {
throw new Exception("sftp异常-->" + e.getMessage());
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
throw new GoPayException("Close stream error");
}
}
disconnect();
}
log.info(">>>>>>>>FtpUtil-->uploadFile--ftp上传文件结束>>>>>>>>>>>>>");
}
/**
* 关闭连接
*/
public static void disconnect() {
if (sftp != null && sftp.isConnected()) {
sftp.disconnect();
sftp = null;
log.info("sftp is closed already");
}
if (sshSession!=null && sshSession.isConnected()) {
sshSession.disconnect();
sshSeddion = null;
log.info("sshSession is closed already");
}
}
}