参考博客: https://blog.csdn.net/u011937566/article/details/81666347
方式一: 使用jsch-0.1.53.jar
0>添加jsch-0.1.52.jar依赖
1>创建JSch对象;
2>通过jsch获取session连接;
3>打开sftp通道Channel;
4>下载/上传文件;
5>退出登录
代码示例:
/**
* 类说明 sftp工具类
*/
public class PSFTPUtil {
private transient Logger log = LoggerFactory.getLogger(this.getClass());
private ChannelSftp sftp;
private Session session;
/** SFTP 登录用户名*/
private String username;
/** SFTP 登录密码*/
private String password;
/** 私钥 */
private String privateKey;
/** SFTP 服务器地址IP地址*/
private String host;
/** SFTP 端口*/
private int port = 22;
/**
* 构造基于密码认证的sftp对象
*/
public PSFTPUtil(String username, String password, String host, int port) {
this.username = username;
this.password = password;
this.host = host;
this.port = port;
}
/**
* 构造基于秘钥认证的sftp对象
*/
public PSFTPUtil(String username, String host, int port, String privateKey) {
this.username = username;
this.host = host;
this.port = port;
this.privateKey = privateKey;
}
public PSFTPUtil() {
}
/**
* 连接sftp服务器
*/
public void login() {
try {
JSch jsch = new JSch();
if (privateKey != null) {
jsch.addIdentity(privateKey);// 设置私钥
}
session = jsch.getSession(username, host, port);
if (password != null) {
session.setPassword(password);
}
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp)channel;
System.out.println("连接成功");
}
catch (JSchException e) {
e.printStackTrace();
System.out.println("连接失败");
}
}
/**
* 关闭连接 server
*/
public void logout() {
if (sftp != null) {
if (sftp.isConnected()) {
sftp.disconnect();
}
}
if (session != null) {
if (session.isConnected()) {
session.disconnect();
}
}
}
/**
* 将输入流的数据上传到sftp作为文件。文件完整路径=basePath+directory
* @param basePath 服务器的基础路径
* @param directory 上传到该目录
* @param sftpFileName sftp端文件名
* @param in 输入流
*/
public void upload(String basePath, String directory, String sftpFileName, InputStream input) throws SftpException {
try {
sftp.cd(basePath);
if(StringUtils.isNotEmpty(directory) && !"".equals(directory)){
sftp.cd(directory);
}
}
catch (SftpException e) {
//目录不存在,则创建文件夹
String[] dirs = directory.split("/");
String tempPath = basePath;
for (String dir : dirs) {
if (null == dir || "".equals(dir))
continue;
tempPath += "/" + dir;
try {
sftp.cd(tempPath);
}
catch (SftpException ex) {
sftp.mkdir(tempPath);
sftp.cd(tempPath);
}
}
}
try {
sftp.put(input, sftpFileName); //上传文件
log.info("上传文件成功");
} catch (SftpException e) {
log.error("上传文件失败",e);
}
}
/**
* 下载文件。
* @param directory 下载目录
* @param downloadFile 下载的文件
* @param saveFile 存在本地的路径
*/
public void download(String directory, String downloadFile, String saveFile) throws SftpException, FileNotFoundException {
if (directory != null && !"".equals(directory)) {
sftp.cd(directory);
}
File file = new File(saveFile);
sftp.get(downloadFile, new FileOutputStream(file));
}
/**
* 下载文件
* @param directory 下载目录
* @param downloadFile 下载的文件名
* @return 字节数组
*/
public byte[] download(String directory, String downloadFile) throws SftpException, IOException {
if (directory != null && !"".equals(directory)) {
sftp.cd(directory);
}
InputStream is = sftp.get(downloadFile);
byte[] fileData = IOUtils.toByteArray(is);
return fileData;
}
/**
* 删除文件
* @param directory 要删除文件所在目录
* @param deleteFile 要删除的文件
*/
public void delete(String directory, String deleteFile) throws SftpException {
sftp.cd(directory);
sftp.rm(deleteFile);
}
/**
* 列出目录下的文件
* @param directory 要列出的目录
* @param sftp
*/
public Vector<?> listFiles(String directory) throws SftpException {
return sftp.ls(directory);
}
//上传文件测试
public static void main(String[] args) throws SftpException, IOException {
PSFTPUtil sftp = new PSFTPUtil("root", "1qazXSW@", "81.68.132.227", 22);
sftp.login();
File file = new File("D:\\jd-gui.exe");
InputStream is = new FileInputStream(file);
sftp.upload("/root", "", "jd-gui.exe", is);
sftp.logout();
}
}
方式二: 使用gaymed-ssh2.jar
0>添加gaymed-ssh2.jar
1> 创建Connection连接
2> 打开一个会话session;
3> 执行脚本并获取结果
//这个jar中提供了很多对象处理命令
//例如使用SCPClient实现文件上传
4>关闭session会话和connection;
public class GanymedUtil {
private static String DEFAULTCHART = "UTF-8";
public static Connection login(String ip, String username, String password) {
boolean flag = false;
Connection connection = null;
try {
connection = new Connection(ip);
connection.connect();// 连接
flag = connection.authenticateWithPassword(username, password);// 认证
if (flag) {
System.out.println("================sftp登录成功==================");
return connection;
}
} catch (IOException e) {
System.out.println("=========sftp登录失败=========" + e);
connection.close();
}
return connection;
}
/**
* 远程执行shll脚本或者命令
*
* @param cmd
* 即将执行的命令
* @return 命令执行完后返回的结果值
*/
public static String execmd(Connection connection, String cmd) {
String result = "";
try{
if (connection != null) {
Session session = connection.openSession();// 打开一个会话
session.execCommand(cmd);// 执行命令
result = processStdout(session.getStdout(), DEFAULTCHART);
System.out.println("物联网文件上传结果:"+result);
// 如果为得到标准输出为空,说明脚本执行出错了
if (StringUtils.isBlank(result)) {
System.out.println("得到标准输出为空,链接conn:" + connection + ",执行的命令:" + cmd);
result = processStdout(session.getStderr(), DEFAULTCHART);
} else {
System.out.println("执行命令成功,链接conn:" + connection + ",执行的命令:" + cmd);
}
connection.close();
session.close();
}
} catch (IOException e) {
System.out.println("执行命令失败,链接conn:" + connection + ",执行的命令:" + cmd + " " + e);
e.printStackTrace();
}
return result;
}
/**
* 解析脚本执行返回的结果集
*
* @param in
* 输入流对象
* @param charset
* 编码
* @return 以纯文本的格式返回
*/
private static String processStdout(InputStream in, String charset) {
InputStream stdout = new StreamGobbler(in);
StringBuffer buffer = new StringBuffer();
;
try {
BufferedReader br = new BufferedReader(new InputStreamReader(stdout, charset));
String line = null;
while ((line = br.readLine()) != null) {
buffer.append(line + "\n");
System.out.println(line);
}
br.close();
} catch (UnsupportedEncodingException e) {
System.out.println("解析脚本出错:" + e.getMessage());
e.printStackTrace();
} catch (IOException e) {
System.out.println("解析脚本出错:" + e.getMessage());
e.printStackTrace();
}
return buffer.toString();
}
public static void main(String[] args) {
long currentTimeMillis = System.currentTimeMillis();
String ip = "182.92.3.78";
String username = "root";
String password = "!QIAOsaifei";
String cmd = "uname -a";
Connection connection = login(ip, username, password);
SCPClient client = new SCPClient(connection);
try {
client.put("E:\\iotfiles\\CU12-4401-2019-000039\\44_CU12-4401-2019-000039_0_11000.zip","/data/all_m2m_dev/d_files_hetong");
} catch (IOException e) {
e.printStackTrace();
}
// String execmd = execmd(connection, cmd);
// System.out.println(execmd);
long currentTimeMillis1 = System.currentTimeMillis();
System.out.println("ganymed-ssh2方式"+(currentTimeMillis1-currentTimeMillis));
}
}
示例: 实现sftp文件上传
Connection connection = GanymedUtil.login(iotHost, iotUsername, iotPassword);
SCPClient client = new SCPClient(connection);
String local_dir = fileFoldPath + File.separator+zipFileName;
String iotRemotAddr="/data/all_m2m_dev/d_files_hetong";
client.put(local_dir,iotRemotAddr);
方式三:使用shell脚本(未认证).
核心命令: put 原文件路径 目标路径
#!/bin/bash
file_input_path=/talkweb/iotfiles/CU12-2203-2019-000002
ftp_output_path=/data/all_m2m_dev/d_files_hetong
file_cache_path=${file_output_path}/.cache
file_name=22_CU12-2203-2019-000002_0_11000.zip
ftp_ip=xx.x.x.xxx
ftp_user=xxxxx
ftp_passwd=xxxxx
#上传文件到cache目录,put命令可强制覆盖
file_cache_path=${ftp_output_path}/.cache
`lftp sftp://${ftp_user}:${ftp_passwd}@${ftp_ip} -e "mkdir -p ${file_cache_path};cd ${file_cache_path};\
rm -f ${file_cache_path}/${file_name};put -c ${file_input_path}/${file_name};\
rm -f ${ftp_output_path}/${file_name};mv ${file_cache_path}/${file_name} ${ftp_output_path}/;quit;" > /dev/null 2>&1`
result=$?
if [ ! ${result} -eq 0 ];then
log_error "Push file:${file_input_path}/${file_name} --> ${ftp_output_path}/ error!"
exit 1
else
log_info "Push file:${file_input_path}/${file_name} --> ${ftp_output_path}/ succeed!"
fi
#成功后删除本地文件
`rm ${file_input_path}/${file_name}`
result=$?
if [ ! ${result} -eq 0 ];then
log_error "Delete local file:${file_input_path}/${file_name} failed!"
exit 1
else
log_info "Delete local file:${file_input_path}/${file_name} succeed!"
fi