|
|
@@ -14,7 +14,7 @@ import java.util.Properties;
|
|
|
import java.util.Vector;
|
|
|
|
|
|
/**
|
|
|
- * SFTP工具类 - 提供SFTP连接管理、文件下载、上传和存在判断功能
|
|
|
+ * SFTPユーティリティクラス - SFTP接続管理、ファイルダウンロード、アップロード、存在確認機能を提供
|
|
|
*
|
|
|
* @author yamoto
|
|
|
* @version 1.0
|
|
|
@@ -24,29 +24,29 @@ public class SftpUtils {
|
|
|
private static final Logger logger = LoggerFactory.getLogger(SftpUtils.class);
|
|
|
|
|
|
/**
|
|
|
- * 默认SFTP端口
|
|
|
+ * デフォルトSFTPポート
|
|
|
*/
|
|
|
private static final int DEFAULT_SFTP_PORT = 22;
|
|
|
|
|
|
/**
|
|
|
- * 默认连接超时时间(毫秒)
|
|
|
+ * デフォルト接続タイムアウト時間(ミリ秒)
|
|
|
*/
|
|
|
private static final int DEFAULT_CONNECT_TIMEOUT = 10000;
|
|
|
|
|
|
/**
|
|
|
- * 默认会话超时时间(毫秒)
|
|
|
+ * デフォルトセッションタイムアウト時間(ミリ秒)
|
|
|
*/
|
|
|
private static final int DEFAULT_SESSION_TIMEOUT = 30000;
|
|
|
|
|
|
/**
|
|
|
- * 建立SFTP连接
|
|
|
+ * SFTP接続を確立
|
|
|
*
|
|
|
- * @param host 主机地址
|
|
|
- * @param port 端口号
|
|
|
- * @param username 用户名
|
|
|
- * @param password 密码
|
|
|
- * @return ChannelSftp对象
|
|
|
- * @throws JSchException SFTP连接异常
|
|
|
+ * @param host ホストアドレス
|
|
|
+ * @param port ポート番号
|
|
|
+ * @param username ユーザー名
|
|
|
+ * @param password パスワード
|
|
|
+ * @return ChannelSftpオブジェクト
|
|
|
+ * @throws JSchException SFTP接続例外
|
|
|
*/
|
|
|
public static ChannelSftp connect(String host, int port, String username, String password) throws JSchException {
|
|
|
JSch jsch = new JSch();
|
|
|
@@ -63,27 +63,27 @@ public class SftpUtils {
|
|
|
ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");
|
|
|
channel.connect();
|
|
|
|
|
|
- logger.info("SFTP连接成功 - 主机: {}, 端口: {}, 用户: {}", host, port, username);
|
|
|
+ logger.info("SFTP接続成功 - ホスト: {}, ポート: {}, ユーザー: {}", host, port, username);
|
|
|
return channel;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 建立SFTP连接(使用默认端口22)
|
|
|
+ * SFTP接続を確立(デフォルトポート22を使用)
|
|
|
*
|
|
|
- * @param host 主机地址
|
|
|
- * @param username 用户名
|
|
|
- * @param password 密码
|
|
|
- * @return ChannelSftp对象
|
|
|
- * @throws JSchException SFTP连接异常
|
|
|
+ * @param host ホストアドレス
|
|
|
+ * @param username ユーザー名
|
|
|
+ * @param password パスワード
|
|
|
+ * @return ChannelSftpオブジェクト
|
|
|
+ * @throws JSchException SFTP接続例外
|
|
|
*/
|
|
|
public static ChannelSftp connect(String host, String username, String password) throws JSchException {
|
|
|
return connect(host, DEFAULT_SFTP_PORT, username, password);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 关闭SFTP连接
|
|
|
+ * SFTP接続を閉じる
|
|
|
*
|
|
|
- * @param channel SFTP通道
|
|
|
+ * @param channel SFTPチャネル
|
|
|
*/
|
|
|
public static void disconnect(ChannelSftp channel) {
|
|
|
if (channel != null) {
|
|
|
@@ -93,152 +93,152 @@ public class SftpUtils {
|
|
|
session = channel.getSession();
|
|
|
channel.disconnect();
|
|
|
} catch (Exception e) {
|
|
|
- logger.warn("关闭SFTP通道时发生异常: {}", e.getMessage());
|
|
|
+ logger.warn("SFTPチャネルを閉じる際に例外が発生: {}", e.getMessage());
|
|
|
}
|
|
|
|
|
|
- // 断开session连接
|
|
|
+ // セッション接続を切断
|
|
|
if (session != null && session.isConnected()) {
|
|
|
try {
|
|
|
session.disconnect();
|
|
|
} catch (Exception e) {
|
|
|
- logger.warn("关闭SFTP会话时发生异常: {}", e.getMessage());
|
|
|
+ logger.warn("SFTPセッションを閉じる際に例外が発生: {}", e.getMessage());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- logger.info("SFTP连接已关闭");
|
|
|
+ logger.info("SFTP接続が閉じられました");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 下载SFTP服务器上的文件
|
|
|
+ * SFTPサーバー上のファイルをダウンロード
|
|
|
*
|
|
|
- * @param channel SFTP通道
|
|
|
- * @param remotePath 远程文件路径
|
|
|
- * @param localPath 本地保存路径
|
|
|
- * @return 下载是否成功
|
|
|
+ * @param channel SFTPチャネル
|
|
|
+ * @param remotePath リモートファイルパス
|
|
|
+ * @param localPath ローカル保存パス
|
|
|
+ * @return ダウンロードが成功したかどうか
|
|
|
*/
|
|
|
public static boolean downloadFile(ChannelSftp channel, String remotePath, String localPath) {
|
|
|
if (channel == null || !channel.isConnected()) {
|
|
|
- logger.error("SFTP通道未连接或已断开");
|
|
|
+ logger.error("SFTPチャネルが接続されていないか、切断されています");
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
try (OutputStream outputStream = new FileOutputStream(localPath)) {
|
|
|
channel.get(remotePath, outputStream);
|
|
|
- logger.info("文件下载成功 - 远程路径: {}, 本地路径: {}", remotePath, localPath);
|
|
|
+ logger.info("ファイルダウンロード成功 - リモートパス: {}, ローカルパス: {}", remotePath, localPath);
|
|
|
return true;
|
|
|
} catch (SftpException | IOException e) {
|
|
|
- logger.error("文件下载失败 - 远程路径: {}, 本地路径: {}, 错误: {}",
|
|
|
+ logger.error("ファイルダウンロード失敗 - リモートパス: {}, ローカルパス: {}, エラー: {}",
|
|
|
remotePath, localPath, e.getMessage());
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 下载SFTP服务器上的文件到字节数组
|
|
|
+ * SFTPサーバー上のファイルをバイト配列としてダウンロード
|
|
|
*
|
|
|
- * @param channel SFTP通道
|
|
|
- * @param remotePath 远程文件路径
|
|
|
- * @return 文件内容的字节数组,失败返回null
|
|
|
+ * @param channel SFTPチャネル
|
|
|
+ * @param remotePath リモートファイルパス
|
|
|
+ * @return ファイル内容のバイト配列、失敗した場合はnullを返す
|
|
|
*/
|
|
|
public static byte[] downloadFileToBytes(ChannelSftp channel, String remotePath) {
|
|
|
if (channel == null || !channel.isConnected()) {
|
|
|
- logger.error("SFTP通道未连接或已断开");
|
|
|
+ logger.error("SFTPチャネルが接続されていないか、切断されています");
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
try (InputStream inputStream = channel.get(remotePath)) {
|
|
|
byte[] fileData = IOUtils.toByteArray(inputStream);
|
|
|
- logger.info("文件下载到字节数组成功 - 远程路径: {}, 文件大小: {} bytes",
|
|
|
+ logger.info("ファイルをバイト配列としてダウンロード成功 - リモートパス: {}, ファイルサイズ: {} バイト",
|
|
|
remotePath, fileData.length);
|
|
|
return fileData;
|
|
|
} catch (SftpException | IOException e) {
|
|
|
- logger.error("文件下载到字节数组失败 - 远程路径: {}, 错误: {}",
|
|
|
+ logger.error("ファイルをバイト配列としてダウンロード失敗 - リモートパス: {}, エラー: {}",
|
|
|
remotePath, e.getMessage());
|
|
|
return null;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 上传本地文件到SFTP服务器
|
|
|
+ * ファイルをSFTPサーバーにアップロード
|
|
|
*
|
|
|
- * @param channel SFTP通道
|
|
|
- * @param localPath 本地文件路径
|
|
|
- * @param remotePath 远程保存路径
|
|
|
- * @return 上传是否成功
|
|
|
+ * @param channel SFTPチャネル
|
|
|
+ * @param localPath ローカルファイルパス
|
|
|
+ * @param remotePath リモート保存パス
|
|
|
+ * @return アップロードが成功したかどうか
|
|
|
*/
|
|
|
public static boolean uploadFile(ChannelSftp channel, String localPath, String remotePath) {
|
|
|
if (channel == null || !channel.isConnected()) {
|
|
|
- logger.error("SFTP通道未连接或已断开");
|
|
|
+ logger.error("SFTPチャネルが接続されていないか、切断されています");
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
try (InputStream inputStream = new FileInputStream(localPath)) {
|
|
|
- // 确保远程目录存在
|
|
|
+ // リモートディレクトリが存在することを確認
|
|
|
createRemoteDirectory(channel, remotePath);
|
|
|
|
|
|
channel.put(inputStream, remotePath);
|
|
|
- logger.info("文件上传成功 - 本地路径: {}, 远程路径: {}", localPath, remotePath);
|
|
|
+ logger.info("ファイルアップロード成功 - ローカルパス: {}, リモートパス: {}", localPath, remotePath);
|
|
|
return true;
|
|
|
} catch (SftpException | IOException e) {
|
|
|
- logger.error("文件上传失败 - 本地路径: {}, 远程路径: {}, 错误: {}",
|
|
|
+ logger.error("ファイルアップロード失敗 - ローカルパス: {}, リモートパス: {}, エラー: {}",
|
|
|
localPath, remotePath, e.getMessage());
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 上传字节数组到SFTP服务器
|
|
|
+ * バイト配列をSFTPサーバーにアップロード
|
|
|
*
|
|
|
- * @param channel SFTP通道
|
|
|
- * @param fileData 文件数据字节数组
|
|
|
- * @param remotePath 远程保存路径
|
|
|
- * @return 上传是否成功
|
|
|
+ * @param channel SFTPチャネル
|
|
|
+ * @param fileData ファイルデータのバイト配列
|
|
|
+ * @param remotePath リモート保存パス
|
|
|
+ * @return アップロードが成功したかどうか
|
|
|
*/
|
|
|
public static boolean uploadBytesToFile(ChannelSftp channel, byte[] fileData, String remotePath) {
|
|
|
if (channel == null || !channel.isConnected()) {
|
|
|
- logger.error("SFTP通道未连接或已断开");
|
|
|
+ logger.error("SFTPチャネルが接続されていないか、切断されています");
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
try (InputStream inputStream = new ByteArrayInputStream(fileData)) {
|
|
|
- // 确保远程目录存在
|
|
|
+ // リモートディレクトリが存在することを確認
|
|
|
createRemoteDirectory(channel, remotePath);
|
|
|
|
|
|
channel.put(inputStream, remotePath);
|
|
|
- logger.info("字节数组上传成功 - 远程路径: {}, 数据大小: {} bytes",
|
|
|
+ logger.info("バイト配列のアップロード成功 - リモートパス: {}, データサイズ: {} バイト",
|
|
|
remotePath, fileData.length);
|
|
|
return true;
|
|
|
} catch (SftpException | IOException e) {
|
|
|
- logger.error("字节数组上传失败 - 远程路径: {}, 错误: {}",
|
|
|
+ logger.error("バイト配列のアップロード失敗 - リモートパス: {}, エラー: {}",
|
|
|
remotePath, e.getMessage());
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 判断SFTP服务器上的文件是否存在
|
|
|
+ * SFTPサーバー上のファイルが存在するか判断
|
|
|
*
|
|
|
- * @param channel SFTP通道
|
|
|
- * @param remotePath 远程文件路径
|
|
|
- * @return 文件是否存在
|
|
|
+ * @param channel SFTPチャネル
|
|
|
+ * @param remotePath リモートファイルパス
|
|
|
+ * @return ファイルが存在するかどうか
|
|
|
*/
|
|
|
public static boolean fileExists(ChannelSftp channel, String remotePath) {
|
|
|
if (channel == null || !channel.isConnected()) {
|
|
|
- logger.error("SFTP通道未连接或已断开");
|
|
|
+ logger.error("SFTPチャネルが接続されていないか、切断されています");
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
channel.lstat(remotePath);
|
|
|
- logger.debug("文件存在 - 远程路径: {}", remotePath);
|
|
|
+ logger.debug("ファイルが存在します - リモートパス: {}", remotePath);
|
|
|
return true;
|
|
|
} catch (SftpException e) {
|
|
|
if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {
|
|
|
- logger.debug("文件不存在 - 远程路径: {}", remotePath);
|
|
|
+ logger.debug("ファイルが存在しません - リモートパス: {}", remotePath);
|
|
|
return false;
|
|
|
} else {
|
|
|
- logger.error("检查文件存在性时发生异常 - 远程路径: {}, 错误: {}",
|
|
|
+ logger.error("ファイルの存在確認中に例外が発生しました - リモートパス: {}, エラー: {}",
|
|
|
remotePath, e.getMessage());
|
|
|
return false;
|
|
|
}
|
|
|
@@ -246,62 +246,62 @@ public class SftpUtils {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 删除SFTP服务器上的文件
|
|
|
+ * SFTPサーバー上のファイルを削除
|
|
|
*
|
|
|
- * @param channel SFTP通道
|
|
|
- * @param remotePath 远程文件路径
|
|
|
- * @return 删除是否成功
|
|
|
+ * @param channel SFTPチャネル
|
|
|
+ * @param remotePath リモートファイルパス
|
|
|
+ * @return 削除が成功したかどうか
|
|
|
*/
|
|
|
public static boolean deleteFile(ChannelSftp channel, String remotePath) {
|
|
|
if (channel == null || !channel.isConnected()) {
|
|
|
- logger.error("SFTP通道未连接或已断开");
|
|
|
+ logger.error("SFTPチャネルが接続されていないか、切断されています");
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
channel.rm(remotePath);
|
|
|
- logger.info("文件删除成功 - 远程路径: {}", remotePath);
|
|
|
+ logger.info("ファイル削除成功 - リモートパス: {}", remotePath);
|
|
|
return true;
|
|
|
} catch (SftpException e) {
|
|
|
- logger.error("文件删除失败 - 远程路径: {}, 错误: {}", remotePath, e.getMessage());
|
|
|
+ logger.error("ファイル削除失敗 - リモートパス: {}, エラー: {}", remotePath, e.getMessage());
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 列出SFTP服务器上指定目录的文件
|
|
|
+ * リモートディレクトリ内のファイルをリスト表示
|
|
|
*
|
|
|
- * @param channel SFTP通道
|
|
|
- * @param remoteDir 远程目录路径
|
|
|
- * @return 文件列表,失败返回null
|
|
|
+ * @param channel SFTPチャネル
|
|
|
+ * @param remoteDir リモートディレクトリパス
|
|
|
+ * @return ファイルリスト,失敗した場合はnull
|
|
|
*/
|
|
|
public static Vector<ChannelSftp.LsEntry> listFiles(ChannelSftp channel, String remoteDir) {
|
|
|
if (channel == null || !channel.isConnected()) {
|
|
|
- logger.error("SFTP通道未连接或已断开");
|
|
|
+ logger.error("SFTPチャネルが接続されていないか、切断されています");
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
Vector<ChannelSftp.LsEntry> files = channel.ls(remoteDir);
|
|
|
- logger.debug("列出文件成功 - 远程目录: {}, 文件数量: {}", remoteDir, files.size());
|
|
|
+ logger.debug("ファイルのリスト表示に成功 - リモートディレクトリ: {}, ファイル数: {}", remoteDir, files.size());
|
|
|
return files;
|
|
|
} catch (SftpException e) {
|
|
|
- logger.error("列出文件失败 - 远程目录: {}, 错误: {}", remoteDir, e.getMessage());
|
|
|
+ logger.error("ファイルのリスト表示に失敗 - リモートディレクトリ: {}, エラー: {}", remoteDir, e.getMessage());
|
|
|
return null;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 创建远程目录(如果不存在)
|
|
|
+ * リモートディレクトリを作成(存在しない場合)
|
|
|
*
|
|
|
- * @param channel SFTP通道
|
|
|
- * @param remotePath 远程路径
|
|
|
+ * @param channel SFTPチャネル
|
|
|
+ * @param remotePath リモートパス
|
|
|
*/
|
|
|
private static void createRemoteDirectory(ChannelSftp channel, String remotePath) {
|
|
|
try {
|
|
|
String directory = remotePath.substring(0, remotePath.lastIndexOf('/'));
|
|
|
if (!directory.isEmpty()) {
|
|
|
- // 递归创建目录
|
|
|
+ // 再帰的にディレクトリを作成
|
|
|
String[] dirs = directory.split("/");
|
|
|
StringBuilder currentPath = new StringBuilder();
|
|
|
|
|
|
@@ -311,7 +311,7 @@ public class SftpUtils {
|
|
|
try {
|
|
|
channel.mkdir(currentPath.toString());
|
|
|
} catch (SftpException e) {
|
|
|
- // 目录已存在,忽略异常
|
|
|
+ // ディレクトリが既に存在する場合、例外を無視
|
|
|
if (e.id != ChannelSftp.SSH_FX_FAILURE) {
|
|
|
throw e;
|
|
|
}
|
|
|
@@ -320,61 +320,8 @@ public class SftpUtils {
|
|
|
}
|
|
|
}
|
|
|
} catch (SftpException e) {
|
|
|
- logger.warn("创建远程目录失败: {}", e.getMessage());
|
|
|
+ logger.warn("リモートディレクトリの作成に失敗: {}", e.getMessage());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 测试SFTP连接
|
|
|
- *
|
|
|
- * @param host 主机地址
|
|
|
- * @param port 端口号
|
|
|
- * @param username 用户名
|
|
|
- * @param password 密码
|
|
|
- * @return 连接是否成功
|
|
|
- */
|
|
|
- public static boolean testConnection(String host, int port, String username, String password) {
|
|
|
- ChannelSftp channel = null;
|
|
|
- try {
|
|
|
- channel = connect(host, port, username, password);
|
|
|
- return channel != null && channel.isConnected();
|
|
|
- } catch (JSchException e) {
|
|
|
- logger.error("SFTP连接测试失败 - 主机: {}, 端口: {}, 用户: {}, 错误: {}",
|
|
|
- host, port, username, e.getMessage());
|
|
|
- return false;
|
|
|
- } finally {
|
|
|
- if (channel != null) {
|
|
|
- disconnect(channel);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 测试SFTP连接(使用默认端口22)
|
|
|
- *
|
|
|
- * @param host 主机地址
|
|
|
- * @param username 用户名
|
|
|
- * @param password 密码
|
|
|
- * @return 连接是否成功
|
|
|
- */
|
|
|
- public static boolean testConnection(String host, String username, String password) {
|
|
|
- return testConnection(host, DEFAULT_SFTP_PORT, username, password);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 主方法 - 测试SFTP功能
|
|
|
- */
|
|
|
- public static void main(String[] args) {
|
|
|
- // 测试连接
|
|
|
- String host = "sftp.example.com";
|
|
|
- String username = "testuser";
|
|
|
- String password = "testpass";
|
|
|
-
|
|
|
- boolean connected = testConnection(host, username, password);
|
|
|
- System.out.println("SFTP连接测试: " + (connected ? "成功" : "失败"));
|
|
|
-
|
|
|
- if (connected) {
|
|
|
- System.out.println("SFTP工具类功能测试完成");
|
|
|
- }
|
|
|
- }
|
|
|
}
|