欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java使用sftp与linux之间进行文件传输解压

程序员文章站 2022-06-01 10:41:04
...

最近有个需求是上传一个压缩包到服务器并实现解压缩,网上找了几个使用ftp上传的例子但是没有实现,各方面总结加上自己的理解编写,最后使用sftp进行涉及,最后实现了文件的上传、下载、删除、解压缩以及文件夹的创建。特此记录下一下,以便不时之需。

1.简单了解 ftp和sftp的区别

在linux系统中,最长使用到的文件传输的方式莫过于ftp和sftp.
FTP(File Transfer Protocol),即文件传输协议,用于Internet上控制文件的双向传输。
FTP在linux系统中,传输默认的端口为21端口,通常以ASCII码和二进制的方式传输数据,支持主动模式和被动模式两种方式。
但Linux默认是不提供ftp的,需要你额外安装FTP服务器。
SFTP(Secure File Transfer Protocol),即文件加密传输协议,
SFTP在linux系统中,传输默认的端口为22端口,这种传输方式更为安全,传输双方既要进行密码安全验证,还要进行基于**的安全验证,有效的防止了“中间人”的威胁和攻击。
在使用linux的centos服务器系统中,两个比较起来,ftp传输会比sftp传输速率快,毕竟sftp牺牲了一定的效率,以保证传输过程的安全。

2.简单了解ChannelSftp类

ChannelSftp类是JSch实现SFTP核心类,它包含了所有SFTP的方法,如:
put(): 文件上传
get(): 文件下载
cd(): 进入指定目录
ls(): 得到指定目录下的文件列表
rename(): 重命名指定文件或目录
rm(): 删除指定文件
mkdir(): 创建目录
rmdir(): 删除目录
还有很多方法,有需要去看源码

2.代码

直接贴代码,里面有注释
SFTPInfo
linux的环境参数

package cn.xgs.file2linux;



/**
 * @version: 1.0
 * @Description:文件上传的环境配置
 * @author: zshuai
 * @date: 2019年4月9日
 */
public class SFTPInfo {  
    public static final String SFTP_REQ_HOST = "192.168.189.138";      //ip
    public static final String SFTP_REQ_USERNAME = "root";      //username
    public static final String SFTP_REQ_PASSWORD = "rootzs";      //password
    public static final int SFTP_DEFAULT_PORT = 22;      //端口
}

SFTPUtil

package cn.xgs.file2linux;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.opensymphony.xwork2.util.finder.ClassFinder.Info;
/**
 * @version: 1.0
 * @Description:文件上传/删除/解压缩
 * @author: zshuai
 * @date: 2019年4月9日
 */
public class SFTPUtil {
	private static final Logger LOG = LoggerFactory.getLogger(SFTPUtil.class);

	/*
	 * @Description: 获取文件上传的安全通道
	 * @param session
	 * @return
	 */
	public static Channel getChannel(Session session) {
		Channel channel = null;
		try {
			channel = session.openChannel("sftp");
			channel.connect();
			System.out.println("获取连接成功");
			LOG.info("get Channel success!");
		} catch (JSchException e) {
			LOG.info("get Channel fail!", e);
		}
		return channel;
	}

	/*
	 * @Description:获取连接信息,返回session,在session中获取安全通道
	 * @param host:连接主机ip
	 * @param port:端口号,一般sftp依托于ssh。端口号22
	 * @param username:用户名
	 * @param password:密码
	 * @return
	 */
	public static Session getSession(String host, int port, String username, final String password) {
		Session session = null;
		try {
			JSch jsch = new JSch();
			jsch.getSession(username, host, port);
			session = jsch.getSession(username, host, port);
			session.setPassword(password);
			Properties sshConfig = new Properties();
			sshConfig.put("StrictHostKeyChecking", "no");
			session.setConfig(sshConfig);
			session.connect();
			LOG.info("Session connected!");
		} catch (JSchException e) {
			LOG.info("get Channel failed!", e);
		}
		return session;
	}

	/*
	 * @Description:创建文件夹
	 * @param sftp
	 * @param dir : 创建的文件夹名字
	 */
	public static Boolean mkdir(String dir) {
		Session s = getSession(SFTPInfo.SFTP_REQ_HOST, SFTPInfo.SFTP_DEFAULT_PORT, SFTPInfo.SFTP_REQ_USERNAME,
				SFTPInfo.SFTP_REQ_PASSWORD);
		Channel channel = getChannel(s);
		ChannelSftp sftp = (ChannelSftp) channel;
		Boolean result = false;
		try {
			sftp.cd("/");//相当于在linux命令行执行cd / ,然后在打开的目录下创建
			sftp.mkdir(dir);
			System.out.println("创建文件夹成功!");
			result = true;
		} catch (SftpException e) {
			System.out.println("创建文件夹失败!");
			result =false;
			e.printStackTrace();
		}
		return result;
	}

	/*
	 * @Description: 文件上传的方法
	 * @param sftp : 客户端
	 * @param dir : 指定上传文件的目录
	 * @param file : 上传的文件
	 * @return :
	 */
	public static Boolean uploadFile(String dir, File file) {
		
		Session s = getSession(SFTPInfo.SFTP_REQ_HOST, SFTPInfo.SFTP_DEFAULT_PORT, SFTPInfo.SFTP_REQ_USERNAME,
				SFTPInfo.SFTP_REQ_PASSWORD);
		Channel channel = getChannel(s);
		ChannelSftp sftp = (ChannelSftp) channel;
		Boolean result =false;
		try {
			sftp.cd("/"+dir);
			System.out.println("打开目录");
			if (file != null) {
				sftp.put(new FileInputStream(file), file.getName());
				result = true;
			} else {
				result = false;
			}
		} catch (Exception e) {
			LOG.info("上传失败!", e);
			result = false;
		}
		closeAll(sftp, channel, s); // 关闭连接
		return result;
	}

	/**
	 * @Description: 文件下载
	 * @param directory    下载目录
	 * @param downloadFile 下载的文件
	 * @param saveFile     存在本地的路径
	 * @param sftp
	 */
	public static Boolean download(String directory, String downloadFile, String saveFile) {
		Session s = getSession(SFTPInfo.SFTP_REQ_HOST, SFTPInfo.SFTP_DEFAULT_PORT, SFTPInfo.SFTP_REQ_USERNAME,
				SFTPInfo.SFTP_REQ_PASSWORD);
		Channel channel = getChannel(s);
		ChannelSftp sftp = (ChannelSftp) channel;
		Boolean result =false;
		try {
			sftp.cd("/"+directory);
			sftp.get(downloadFile, saveFile);
			result = true;
		} catch (Exception e) {
			result = false;
			LOG.info("下载失败!", e);
			;
		}
		return result;
	}
	/**
	 * @Description: 文件删除
	 * @param directory  要删除文件所在目录
	 * @param deleteFile 要删除的文件
	 * @param sftp
	 */
	public static Boolean delete(String directory, String deleteFile ) {
		Session s = getSession(SFTPInfo.SFTP_REQ_HOST, SFTPInfo.SFTP_DEFAULT_PORT, SFTPInfo.SFTP_REQ_USERNAME,
				SFTPInfo.SFTP_REQ_PASSWORD);
		Channel channel = getChannel(s);
		ChannelSftp sftp = (ChannelSftp) channel;
		Boolean result = false;
		try {
			sftp.cd("/"+directory);
			sftp.rm(deleteFile);
			result = true;
		} catch (Exception e) {
			result = false;
			LOG.info("删除失败!", e);
		}
		return result;
	}

	private static void closeChannel(Channel channel) {
		if (channel != null) {
			if (channel.isConnected()) {
				channel.disconnect();
			}
		}
	}

	private static void closeSession(Session session) {
		if (session != null) {
			if (session.isConnected()) {
				session.disconnect();
			}
		}
	}

	public static void closeAll(ChannelSftp sftp, Channel channel, Session session) {
		try {
			closeChannel(sftp);
			closeChannel(channel);
			closeSession(session);
		} catch (Exception e) {
			LOG.info("closeAll", e);
		}
	}
}

ExtractUtils

package cn.xgs.file2linux;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;

import ch.ethz.ssh2.ChannelCondition;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;

/**
 * @version: 1.0
 * @Description: 远程解压缩指定目录下的指定名字的文件
 * @author: zshuai
 * @date: 2019年4月9日
 */
public class ExtractUtils {

	/*
	 * @Description:远程解压缩指定目录下的指定名字的文件
	 * @param path:指定解压文件的目录
	 * @param fileName:需要解压的文件名字
	 * @param decpath :解压完成后的存放路径
	 */
	public static Boolean remoteZipToFile(/*String path, */String fileName /*, String decpath/**/) {
		String path = "zshuaipath";
		String decpath = "zshuai";
		Boolean result =false;
		try {
			Connection connection = new Connection(SFTPInfo.SFTP_REQ_HOST);// 创建一个连接实例
			connection.connect();// Now connect
			boolean isAuthenticated = connection.authenticateWithPassword(SFTPInfo.SFTP_REQ_USERNAME,
					SFTPInfo.SFTP_REQ_PASSWORD);// Authenticate
			if (isAuthenticated == false)
				throw new IOException("user and password error");
			Session sess = connection.openSession();// Create a session
			System.out.println("start exec command.......");
			sess.requestPTY("bash");
			sess.startShell();
			InputStream stdout = new StreamGobbler(sess.getStdout());
			InputStream stderr = new StreamGobbler(sess.getStderr());
			BufferedReader stdoutReader = new BufferedReader(new InputStreamReader(stdout));
			BufferedReader stderrReader = new BufferedReader(new InputStreamReader(stderr));
			PrintWriter out = new PrintWriter(sess.getStdin());
			out.println("cd /" + path + "/");
			out.println("ll");
			// out.println("unzip -o " + fileName + "  -d /" + decpath + "/");//解压zip格式
			out.println("tar zxvf " + fileName + "  -C /" + decpath + "/");//解压tar格式
			out.println("ll");
			out.println("exit");
			out.close();
			sess.waitForCondition(ChannelCondition.CLOSED | ChannelCondition.EOF | ChannelCondition.EXIT_STATUS, 30000);
			System.out.println("下面是从stdout输出:");
			while (true) {
				String line = stdoutReader.readLine();
				if (line == null)
					break;
				System.out.println(line);
			}
			System.out.println("下面是从stderr输出:");
			while (true) {
				String line = stderrReader.readLine();
				if (line == null)
					break;
				System.out.println(line);
			}
			System.out.println("ExitCode: " + sess.getExitStatus());
			sess.close();/* Close this session */
			connection.close();/* Close the connection */
			result = true;
		} catch (IOException e) {
			e.printStackTrace(System.err);
			result =false;
			System.exit(2);
		}
		return result;
		
	}

}

TestFtp

package cn.xgs.test;

import java.io.File;

import org.junit.Test;

import cn.xgs.file2linux.ExtractUtils;
import cn.xgs.file2linux.SFTPUtil;


public class TestFtp {

	@Test
	//测试文件上传
	public void testuploadfile() {
		File file = new File("D://linux-4.20.tar.gz");
		long startTime = System.currentTimeMillis();//获取当前时间
		Boolean uploadFile = SFTPUtil.uploadFile("zshuaipath", file);
		Boolean remoteZipToFile = false;
		if (uploadFile) {
			System.out.println("上传成功,开始解压");
			remoteZipToFile = ExtractUtils.remoteZipToFile("linux-4.20.tar.gz");
		}
		long endTime = System.currentTimeMillis();
		System.out.println("程序运行时间:"+(endTime-startTime)+"ms");
		System.out.println(remoteZipToFile);
	}
	
	@Test
	//测试文件下载
	public void testdownloadfile() {
		long startTime = System.currentTimeMillis();//获取当前时间
		 Boolean download = SFTPUtil.download("zshuaipath","linux-4.20.tar.gz", "D://1");
		long endTime = System.currentTimeMillis();
		System.out.println("程序运行时间:"+(endTime-startTime)+"ms");
		System.out.println(download);
	}
	
	@Test
	//测试文件删除
	public void testdeletefile() {
		long startTime = System.currentTimeMillis();//获取当前时间
		Boolean delete = SFTPUtil.delete("zshuaipath","linux-4.20.tar.gz");
		long endTime = System.currentTimeMillis();
		System.out.println("程序运行时间:"+(endTime-startTime)+"ms");
		System.out.println(delete);
	}
	@Test
	//测试文件夹的创建
	public void testmkdir() {
		long startTime = System.currentTimeMillis();//获取当前时间
		Boolean mkdir = SFTPUtil.mkdir("zshuaipath");
		long endTime = System.currentTimeMillis();
		System.out.println("程序运行时间:"+(endTime-startTime)+"ms");
		System.out.println(mkdir);
	}
	
	@Test
	//测试指定目录下的指定文件的解压缩
	public void testExtract() {
		long startTime = System.currentTimeMillis();//获取当前时间
		Boolean remoteZipToFile = ExtractUtils.remoteZipToFile("linux-4.20.tar.gz");
		long endTime = System.currentTimeMillis();
		System.out.println("程序运行时间:"+(endTime-startTime)+"ms");
		System.out.println(remoteZipToFile);
	}

}

主要的pom文件

<properties>
		<spring.version>4.2.4.RELEASE</spring.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>commons-net</groupId>
			<artifactId>commons-net</artifactId>
			<version>3.1</version>
		</dependency>
		<dependency>
			<groupId>ch.ethz.ganymed</groupId>
			<artifactId>ganymed-ssh2</artifactId>
			<version>build210</version>
		</dependency>
		<!-- stringutils -->
		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>2.6</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.jcraft/jsch -->
		<dependency>
			<groupId>com.jcraft</groupId>
			<artifactId>jsch</artifactId>
			<version>0.1.55</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.opensymphony/xwork -->
		<dependency>
			<groupId>com.opensymphony</groupId>
			<artifactId>xwork</artifactId>
			<version>2.1.3</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>1.7.26</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<!-- java编译插件 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.2</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
					<encoding>UTF-8</encoding>
				</configuration>
			</plugin>
		</plugins>
	</build>

参考的文章:
https://www.cnblogs.com/lvgg/p/6672641.html
https://blog.csdn.net/u012540337/article/details/20720785

相关标签: sftp