本文主要是介绍java实现与远程 SFTP 服务器之间安全文件传输,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 概要
- FTP SFTP区别
- 封装一个工具类
概要
SFTP
(Secure File Transfer Protocol)是一种基于SSH(Secure Shell)协议的安全文件传输协议
,它提供了在安全信道上进行数据传输的能力。相比传统的FTP(File Transfer Protocol),SFTP具有更高的安全性和更多的功能。
FTP SFTP区别
FTP和SFTP之间的一些主要区别:
特征 | FTP | SFTP |
---|---|---|
协议 | 基于传统的FTP协议(File Transfer Protocol) | 基于SSH的安全文件传输协议(Secure File Transfer Protocol) |
安全性 | 不安全,数据传输未加密 | 安全,所有数据均经过SSH加密传输 |
端口 | 默认端口为21 | 默认端口为22 |
认证 | 可以使用用户名和密码进行简单认证 | 通过SSH密钥或用户名密码进行认证 |
加密 | 不支持加密 | 所有数据传输都通过SSH加密保护 |
目录访问控制 | 依赖FTP服务器的权限和文件系统权限 | 依赖SSH服务器的权限和文件系统权限 |
使用场景 | 用于需要简单文件传输,无需考虑安全性的场景 | 用于需要安全文件传输和操作的场景 |
适用性 | 适用于内部网络和不涉及敏感信息的场景 | 适用于需要加密和安全性要求较高的场景 |
封装一个工具类
import com.jcraft.jsch.*;import java.io.*;
import java.util.Properties;
import java.util.Vector;public class SftpUtil {public static final String NO_FILE = "No such file";public enum UploadStatus {Create_Directory_Fail,Create_Directory_Success,Upload_New_File_Success,Upload_New_File_Failed,File_Exits,Remote_Bigger_Local,Upload_From_Break_Success,Upload_From_Break_Failed,Delete_Remote_Faild;}private ChannelSftp sftp = null;private Session sshSession = null;private String username;private String password;private String host;private int port;public SftpUtil(String host, int port, String username, String password) {this.username = username;this.password = password;this.host = host;this.port = port;}/*** 连接到sftp服务器*/public ChannelSftp connect() throws Exception {JSch jsch = new JSch();try {jsch.getSession(username, host, port);sshSession = jsch.getSession(username, host, port);sshSession.setPassword(password);Properties properties = new Properties();properties.put("StrictHostKeyChecking", "no");sshSession.setConfig(properties);sshSession.connect();Channel channel = sshSession.openChannel("sftp");channel.connect();sftp = (ChannelSftp)channel;} catch (JSchException e) {throw new Exception("FtpUtil-->connect异常" + e.getMessage());}return sftp;}/*** 关闭连接*/public void disconnect() {if (this.sftp != null) {if (this.sftp.isConnected()) {this.sftp.disconnect();this.sftp = null;}}if (this.sshSession != null) {if (this.sshSession.isConnected()) {this.sshSession.disconnect();this.sshSession = null;}}}/*** 上传文件* 用于将本地文件上传到指定的远程目录,并且使用给定的文件名。适用于将现有的本地文件上传到SFTP服务器的情况。** @param directory 远程上传目录* @param uploadFilePath 本地文件路径* @param fileName 远程文件名* @throws Exception 可能抛出的异常*/public void uploadFile(String directory, String uploadFilePath, String fileName) throws Exception {FileInputStream in = null;connect();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 {in = new FileInputStream(file);sftp.put(in, fileName);} catch (FileNotFoundException e) {throw new Exception("文件不存在-->" + uploadFilePath);} catch (SftpException e) {throw new Exception("sftp异常-->" + e.getMessage());} finally {if (in != null) {try {in.close();} catch (IOException e) {throw new Exception("Close stream error." + e.getMessage());}}disconnect();}}/*** 上传文件* 将文件从一个输入流上传到指定的远程路径和文件名。适用于需要从内存中的输入流直接上传文件的情况。** @param filePath 远程文件路径* @param filename 文件名* @param in 输入流* @return 上传状态*/public UploadStatus uploadFile(String filePath, String filename, InputStream in) {try {sftp.put(in, filePath + filename, ChannelSftp.OVERWRITE);} catch (SftpException e) {e.printStackTrace();}return UploadStatus.Upload_From_Break_Success;}/*** 获取文件列表** @param filePath 远程文件路径* @return 文件列表*/public Vector<LsEntry> getFileList(String filePath) {Vector<LsEntry> list = new Vector<>();try {Vector veItem = sftp.ls(filePath);for (Object obj : veItem) {if (obj instanceof LsEntry) {list.add((LsEntry)obj);}}} catch (SftpException e) {e.printStackTrace();}return list;}/*** 下载文件** @param directory 远程下载目录* @param remoteFileName 远程文件名* @param localFile 本地文件路径* @return 下载的文件对象* @throws Exception 可能抛出的异常*/public File downloadFile(String directory, String remoteFileName, String localFile) throws Exception {connect();File file = null;OutputStream output = null;try {file = new File(localFile);if (file.exists()) {file.delete();}file.createNewFile();sftp.cd(directory);output = new FileOutputStream(file);sftp.get(remoteFileName, output);} catch (SftpException e) {if (e.toString().equals(NO_FILE)) {throw new Exception("FtpUtil-->downloadFile--ftp下载文件失败" + directory + remoteFileName + "不存在");}throw new Exception("ftp目录或者文件异常,检查ftp目录和文件" + e.toString());} catch (FileNotFoundException e) {throw new Exception("本地目录异常,请检查" + file.getPath() + e.getMessage());} catch (IOException e) {throw new Exception("创建本地文件失败" + file.getPath() + e.getMessage());} finally {if (output != null) {try {output.close();} catch (IOException e) {throw new Exception("Close stream error." + e.getMessage());}}disconnect();}return file;}}
解释代码:
connect()
函数:
- 创建
JSch
对象。 - 通过
getSession
方法获取会话,并设置用户名、主机、端口和密码。 - 创建属性对象,并将
StrictHostKeyChecking
设置为no
,然后应用到会话配置中。 - 连接会话。
- 打开
sftp
通道并进行连接。 - 将通道强转为
ChannelSftp
类型并赋值给sftp
。 - 最后返回
sftp
对象。
disconnect()
函数:
- 检查
sftp
对象是否不为空且已连接,如果是,则断开连接并将其置为null
。 - 检查
sshSession
对象是否不为空且已连接,如果是,则断开连接并将其置为null
。
public void uploadFile(String directory, String uploadFilePath, String fileName) throws Exception {}
方法:
- 调用
connect
方法建立连接。 - 尝试切换到指定的目录,如果目录不存在则创建目录后再切换。
- 读取要上传的文件,并通过
sftp.put
方法将文件上传。 - 处理可能出现的文件未找到、
SFTP
异常等情况。 - 在
finally
块中,若文件输入流不为空则关闭,并调用disconnect
方法断开连接。
downloadFile
函数:
- 调用
connect
方法建立连接。 - 创建本地文件,如果文件已存在则先删除再创建新文件。
- 切换到指定目录。
- 创建文件输出流。
- 通过
sftp.get
方法从远程获取文件并写入本地输出流。 - 处理可能出现的
SFTP
异常、文件未找到异常、本地目录异常、创建本地文件异常等情况。 - 在
finally
块中,若输出流不为空则关闭,并调用disconnect
方法断开连接。 - 最后返回下载的本地文件。
❤觉得有用的可以留个关注~❤
这篇关于java实现与远程 SFTP 服务器之间安全文件传输的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!