如何在JSCH中创建新目录之前检查目录是否存在

12
如何在使用JSCH SFTP API创建新目录之前检查目录的存在?我正在尝试使用lstat,但不确定它是否可以完成我需要的工作。先行致谢。
3个回答

18

这是我在JSch中检查目录是否存在的方法。

如果目录不存在,则创建该目录。

ChannelSftp channelSftp = (ChannelSftp)channel;
String currentDirectory=channelSftp.pwd();
String dir="abc";
SftpATTRS attrs=null;
try {
    attrs = channelSftp.stat(currentDirectory+"/"+dir);
} catch (Exception e) {
    System.out.println(currentDirectory+"/"+dir+" not found");
}

if (attrs != null) {
    System.out.println("Directory exists IsDir="+attrs.isDir());
} else {
    System.out.println("Creating dir "+dir);
    channelSftp.mkdir(dir);
}

据我所记,当attrs未找到目录时,它不会为空,而是会抛出异常。 - SRy
1
我认为你的代码并没有按照你预期的那样工作。因为当上述代码中没有目录存在时抛出异常,你假设控制将转到 else 代码块,而且没有机会控制转到 if-else 代码块。因此,你的代码只有在 attrs 不为空时才能工作。 - SRy
1
异常将在try catch块下的“attrs = channelSftp.stat(currentDirectory +” / “+ dir);”行中抛出。稍后它将继续执行if else部分。如果attrs值未更改(即为null),则它将进入else部分并创建目录。 - AabinGunz
是的,我很抱歉,你是正确的。早上好啊。我需要喝点咖啡了。我对异常没有好好思考。 - SRy
4
我认为异常处理太过于着急,可以更具体:try { channel.stat(folderName); } catch (SftpException e) { if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) { channel.mkdir(folderName); } else { throw e; } } - Ton Bosma
显示剩余2条评论

13
在这种情况下,最好的方法是直接创建并处理错误。这样操作是原子的,并且在SSH的情况下还能节省大量的网络流量。如果先进行测试,那么就会有一个时间窗口,在这期间情况可能会发生变化,你仍需要处理错误结果。

但是我只能创建目录一次。之后,当用户将文件上传到我们的应用程序时,我必须检查目录是否存在。那么,有没有其他方法可以做到这一点? - SRy
@Srinivas 当然你只能创建它一次。之后你会得到一个错误。处理它。就像我上面说的那样。 - user207421
好的,明白了。谢谢,之前我没理解清楚。现在清楚了,谢谢。 - SRy

4

我在这里以更广泛的背景重复相同的答案。检查目录是否存在并创建新目录的特定代码行是

            SftpATTRS attrs;
            try {
                attrs = channel.stat(localChildFile.getName());
            }catch (Exception e) {
                channel.mkdir(localChildFile.getName());
            }

注意: localChildFile.getName() 是您要检查的目录名称。下面附上整个类,该类会递归地将文件或目录内容发送到远程服务器。

import com.jcraft.jsch.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;

/**
 * Created by krishna on 29/03/2016.
 */
public class SftpLoader {
private static Logger log = LoggerFactory.getLogger(SftpLoader.class.getName());

ChannelSftp channel;
String host;
int    port;
String userName ;
String password ;
String privateKey ;


public SftpLoader(String host, int port, String userName, String password, String privateKey) throws JSchException {
    this.host = host;
    this.port = port;
    this.userName = userName;
    this.password = password;
    this.privateKey = privateKey;
    channel = connect();
}

private ChannelSftp connect() throws JSchException {
    log.trace("connecting ...");

    JSch jsch = new JSch();
    Session session = jsch.getSession(userName,host,port);
    session.setPassword(password);
    jsch.addIdentity(privateKey);
    java.util.Properties config = new java.util.Properties();
    config.put("StrictHostKeyChecking", "no");
    session.setConfig(config);
    session.connect();
    Channel channel = session.openChannel("sftp");
    channel.connect();
    log.trace("connected !!!");
    return (ChannelSftp)channel;
}

public void transferDirToRemote(String localDir, String remoteDir) throws SftpException, FileNotFoundException {
    log.trace("local dir: " + localDir + ", remote dir: " + remoteDir);

    File localFile = new File(localDir);
    channel.cd(remoteDir);

    // for each file  in local dir
    for (File localChildFile: localFile.listFiles()) {

        // if file is not dir copy file
        if (localChildFile.isFile()) {
           log.trace("file : " + localChildFile.getName());
            transferFileToRemote(localChildFile.getAbsolutePath(),remoteDir);

        } // if file is dir
        else if(localChildFile.isDirectory()) {

            // mkdir  the remote
            SftpATTRS attrs;
            try {
                attrs = channel.stat(localChildFile.getName());
            }catch (Exception e) {
                channel.mkdir(localChildFile.getName());
            }

            log.trace("dir: " + localChildFile.getName());

            // repeat (recursive)
            transferDirToRemote(localChildFile.getAbsolutePath(), remoteDir + "/" + localChildFile.getName());
            channel.cd("..");
        }
    }

}

 public void transferFileToRemote(String localFile, String remoteDir) throws SftpException, FileNotFoundException {
   channel.cd(remoteDir);
   channel.put(new FileInputStream(new File(localFile)), new File(localFile).getName(), ChannelSftp.OVERWRITE);
}


public void transferToLocal(String remoteDir, String remoteFile, String localDir) throws SftpException, IOException {
    channel.cd(remoteDir);
    byte[] buffer = new byte[1024];
    BufferedInputStream bis = new BufferedInputStream(channel.get(remoteFile));

    File newFile = new File(localDir);
    OutputStream os = new FileOutputStream(newFile);
    BufferedOutputStream bos = new BufferedOutputStream(os);

    log.trace("writing files ...");
    int readCount;
    while( (readCount = bis.read(buffer)) > 0) {
        bos.write(buffer, 0, readCount);
    }
    log.trace("completed !!!");
    bis.close();
    bos.close();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接