Java jsch.ChannelSftp - 如何知道 mkdir 是否因目录已存在而失败

Java jsch.ChannelSftp - How to know if mkdir failed due to a directory alread existing

我正在使用 com.jcraft.jsch.ChannelSftp 作为我的 SFTP 客户端。

我想尝试创建一个目录,如果因为目录已经存在而失败,就当什么都没发生一样继续。如果因为其他原因失败,例如网络错误,我想停止执行程序。

import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.SftpException;

ChannelSftp sftpClient;
//...
try {
    sftpClient.mkdir("test")
} catch (SftpException e) {
    System.out.println(e.id); // Prints "Failure"
    System.out.println(e.getMessage()); // Prints "null"
    assert (e.id == ChannelSftp.SSH_FX_FAILURE);
    assert (e.id == 4);
}

这次失败的 ID 是 4

我注意到如果我 mkdir 在我没有权限的目录中,异常的 ID 将是 3/SSH_FX_PERMISSION_DENIED.

如何确定 mkdir 是否因为目录已经创建而失败?

如果 id 是 4,那么失败是由于文件夹已经存在是否安全?

Jsch 实现 SFTP version 3. Section 7 of that RFC 定义从 SFTP 服务器到客户端的响应,包括状态代码。这是列表:

    #define SSH_FX_OK                            0
    #define SSH_FX_EOF                           1
    #define SSH_FX_NO_SUCH_FILE                  2
    #define SSH_FX_PERMISSION_DENIED             3
    #define SSH_FX_FAILURE                       4
    #define SSH_FX_BAD_MESSAGE                   5
    #define SSH_FX_NO_CONNECTION                 6
    #define SSH_FX_CONNECTION_LOST               7
    #define SSH_FX_OP_UNSUPPORTED                8

RFC 表示只要没有更具体的错误代码,就会返回 SSH_FX_FAILURE。为 mkdir() 获取它并不特别意味着已经有一个具有请求名称的目录。例如,如果有一个具有预期名称的 file,我希望您能得到它。或者,如果您尝试在 read-only 文件系统上创建目录。

ChannelSftp has two functions named stat() and lstat() 可用于获取有关文件或目录的信息。当您的 mkdir() 调用失败并显示 SSH_FX_FAILURE 时,您可以在路径上调用 stat() 以查看该文件是否实际存在以及它是否是一个目录。