您的位置:首页 > 编程语言 > PHP开发

sftp实现OS之间的远程传输文件与文件夹

2017-06-23 19:01 344 查看

问题场景

最近的项目可能会要求从Linux环境与Windows进行文件传输,实现方式很多,本文采用com.jcraft.jsch_0.1.31.jar,支持递归上传、下载、删除文件夹或者文件。算是对scp实现OS之间的远程传输文件的补充。

CODE

package com.business.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Vector;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpATTRS;
import com.jcraft.jsch.SftpException;

/**
* @author  youxingyang
* @Date    2017-6-26 上午9:27:32
*/
public final class FtpUtils {

private static String separator = "/";
/**
* 连接sftp服务器
* @param host     主机
* @param port     端口
* @param username 用户名
* @param password 密码
* @return
*/
public static ChannelSftp connect(String host, int port, String username, String password) {

ChannelSftp sftp = null;
try {
JSch jsch = new JSch();
jsch.getSession(username, host, port);
Session sshSession = jsch.getSession(username, host, port);
System.out.println("Session created.");
sshSession.setPassword(password);
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();
System.out.println("Session connected.");
System.out.println("Opening Channel.");
Channel channel = sshSession.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
System.out.println("Connected to " + host + ".");
} catch (Exception e) {
e.printStackTrace();
}
return sftp;
}

/**
* 列出目录下的文件
*
* @param directory 要列出的目录
* @param sftp
* @return
* @throws SftpException
*/
public Vector<?> listFiles(String directory, ChannelSftp sftp) throws SftpException {
return sftp.ls(directory);
}

/**
* 删除-单个文件
* @param directory  要删除文件所在目录
* @param deleteFile 要删除的文件
* @param sftp
*/

public void delete(String directory, String deleteFile, ChannelSftp sftp) {
try {
sftp.cd(directory);
sftp.rm(deleteFile);
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 删除文件夹或者文件
* @param path 文件夹或者文件路径
* @param sftp sftp
* @param resursion 是否递归删除文件夹
* @throws Exception 异常
*/
public static void deleteFile(String path, ChannelSftp sftp, boolean recursion) throws Exception {
try {
if (isDirExist(sftp, path)) {
if (recursion)
doDeleteFile(path, sftp);
else
sftp.rmdir(path);
} else {
sftp.rm(path);
}
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 递归删除执行
* @param pathString 文件路径
* @param sftp sftp连接
* @throws SftpException
*/
private static void doDeleteFile(final String pathString, final ChannelSftp sftp) throws SftpException {
@SuppressWarnings("unchecked")
Vector<LsEntry> vector = sftp.ls(pathString);
if (vector.size() == 1) { // 文件,直接删除
sftp.rm(pathString);
} else if (vector.size() == 2) { // 空文件夹,直接删除
sftp.rmdir(pathString);
} else {
String fileName = "";
// 删除文件夹下所有文件
for (LsEntry en : vector) {
fileName = en.getFilename();
if (".".equals(fileName) || "..".equals(fileName)) {
continue;
} else {
doDeleteFile(pathString + separator + fileName, sftp);
}
}
// 删除文件夹
sftp.rmdir(pathString);//rmdir只能删除空的文件夹
}
}

public static void mkdir(String directory, ChannelSftp sftp) {
try {
sftp.ls(directory);
} catch (SftpException e) {
try {
sftp.mkdir(directory);
} catch (SftpException ex) {
ex.printStackTrace();
}
}
}

public static void mkdirs(String directory, ChannelSftp sftp) {
List<String> fileNames = getFileNames(directory);
StringBuffer buf = new StringBuffer();
if (fileNames != null && fileNames.size() > 0) {
for (String fileName : fileNames) {
buf.append(separator);
buf.append(fileName);
mkdi
f2ce
r(buf.toString(), sftp);
}
}
}

/**
* 列出目录下的所有文件及文件夹
* @param dir
* @return
*/
public static List<String> getFileNames(String dir) {
File file = new File(dir);
List<String> list = new ArrayList<String>();
if (file.getParentFile() != null) {
List<String> fileNames = getFileNames(file.getParentFile().getPath());
for (String fileName : fileNames) {
if (fileName != null && !fileName.equals(""))
list.add(fileName);
}
}
if (!file.getName().equals(""))
list.add(file.getName());
return list;
}

/**
* 下载文件-单个文件
* @param directory    下载目录
* @param downloadFile 下载的文件
* @param saveFile     存在本地的路径
* @param sftp
*/

public void download(String directory, String downloadFile, String saveFile, ChannelSftp sftp) {
try {
sftp.cd(directory);
File file = new File(saveFile);
sftp.get(downloadFile, new FileOutputStream(file));
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 下载文件-支持文件夹
* @param sftp          sftp
* @param ftpPath       ftp上的路径-文件夹或者文件路径
* @param localPath     本地路径
*/
public static void downloadFile(ChannelSftp sftp, String ftpPath, String localPath) {
try {
//要下载的是一个目录
if (isDirExist(sftp, ftpPath)) {
Vector<?> v = sftp.ls(ftpPath);
for (Object object : v) {
ChannelSftp.LsEntry entry = (ChannelSftp.LsEntry) object;
doDownloadFile(sftp, entry, ftpPath, localPath);
}
} else {
File file = new File(ftpPath);
sftp.get(localPath, new FileOutputStream(file));
}
} catch (SftpException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}

/**
* 从远端递归下载数据到本地-支持文件夹
* @param sftp
* @param entry         文件实体
* @param ftpPath       ftp上的文件路径
* @param localPath     存储下载文件的路径
*/
public static void doDownloadFile(ChannelSftp sftp, ChannelSftp.LsEntry entry, String ftpPath, String localPath) {
try {
SftpATTRS attrs = entry.getAttrs();
String filename = entry.getFilename();
if (filename.equals(".") || filename.equals("..")) {
return;
}
String nextFtpPath = getRealName(ftpPath, filename);
String nextLocalPath = getRealName(localPath, filename);
if (attrs.isDir()) {
sftp.cd(nextFtpPath);

Vector<?> v = sftp.ls(sftp.pwd());
for (Object object : v) {
ChannelSftp.LsEntry entry1 = (ChannelSftp.LsEntry) object;
doDownloadFile(sftp, entry1, nextFtpPath, nextLocalPath);
}
} else {
File file = new File(nextLocalPath);
// 如果路径不存在,则创建
File parentFile = file.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdirs();
}
sftp.get(nextFtpPath, new FileOutputStream(nextLocalPath));
}
} catch (SftpException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}

private static String getRealName(String pwd, String filename) {
return pwd.endsWith(separator) ? pwd + filename : pwd + separator + filename;
}

/**
* 上传文件-单个文件
*
* @param directory  上传的目录
* @param uploadFile 要上传的文件
* @param sftp
*/
public void upload(InputStream is, String directory, String uploadFile, ChannelSftp sftp) {
try {
sftp.cd(directory);
File file = new File(uploadFile);
sftp.put(is, file.getName());
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 上传文件-支持文件夹
* @param sftp          sftp
* @param localPath     要传的文件夹或者文件路径
* @param ftpPath       目标位置
*/
public static void uploadFile(ChannelSftp sftp, String localPath, String ftpPath) {

try {
//如果目标目录不存在则捕获异常创建
try {
sftp.cd(ftpPath);
} catch (SftpException e) {
mkdirs(ftpPath, sftp);
sftp.cd(ftpPath);
}
File file = new File(localPath);
doUploadFile(sftp, file, sftp.pwd());
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 从本地递归上传数据到远端-支持文件夹
* @param sftp  sftp
* @param file  文件或者文件夹
* @param pwd   当前目录
*/
public static void doUploadFile(ChannelSftp sftp, File file, String pwd) {
try {
if (file.isDirectory()) {
File[] list = file.listFiles();
String fileName = file.getName();
sftp.cd(pwd);
pwd = pwd + separator + file.getName();
if (!isDirExist(sftp, pwd)) {
sftp.mkdir(fileName);
}
//切换到下一级文件夹
sftp.cd(file.getName());
for (File aList : list) {
doUploadFile(sftp, aList, pwd);
}
} else {
sftp.cd(pwd);
sftp.put(new FileInputStream(file), file.getName());
}
} catch (SftpException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}

/**
* 判断目录是否存在
* @param directory
* @return
*/
public static boolean isDirExist(ChannelSftp sftp, String directory) {
boolean isDirExistFlag = false;
try {
SftpATTRS sftpATTRS = sftp.lstat(directory);
isDirExistFlag = sftpATTRS.isDir();
} catch (Exception e) {
if (e.getMessage().toLowerCase().equals("no such file")) {
isDirExistFlag = false;
}
}
return isDirExistFlag;
}

public static void main(String[] args) {
String host = "192.168.XXX.XXX";
int port = 22;
String username = "root";
String password = "master";
ChannelSftp sftp = connect(host, port, username, password);

// upload paths
String ftpPathUpload = "/samples/a/b/";//不是root权限注意能否使用根目录
//file
//String localPathFileUpload = "/Users/yyx/IdeaProjects/study/lib/com.jcraft.jsch_0.1.31.jar";
//directory
String localPathDirUpload = "E:\\1报告数据\\XXX\\全自动化\\全自动化-x\\XXX\\TB_0001";

//download paths
String localPathDownload = "E:\\TB_0001";
String ftpPathDownload = "/samples/a/b/TB_0001/";
try {

uploadFile(sftp, localPathDirUpload, ftpPathUpload);
System.out.println("upload finished");

downloadFile(sftp, ftpPathDownload, localPathDownload);
System.out.println("download finished");

deleteFile("/samples/a/b/", sftp, true);
System.out.println("delete finished");

} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
sftp.quit();
sftp.getSession().disconnect();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  递归 java sftp