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

Java 如何在JSCH中创建新目录之前检查目录是否存在,java,directory,jsch,Java,Directory,Jsch,如何在使用JSCH SFTP API创建新目录之前检查目录的存在性?我正在尝试使用lstat,但不确定它是否完成了我需要的工作。提前感谢在这种情况下,最好只创建并处理错误。这样,操作是原子的,在SSH的情况下,还可以节省大量网络流量。如果您先进行测试,则会有一个计时窗口,在此期间情况可能会发生变化,您必须处理错误结果。这就是我在中检查目录存在的方式 如果目录不存在,则创建目录 ChannelSftp channelSftp = (ChannelSftp)channel; String curre

如何在使用JSCH SFTP API创建新目录之前检查目录的存在性?我正在尝试使用
lstat
,但不确定它是否完成了我需要的工作。提前感谢在这种情况下,最好只创建并处理错误。这样,操作是原子的,在SSH的情况下,还可以节省大量网络流量。如果您先进行测试,则会有一个计时窗口,在此期间情况可能会发生变化,您必须处理错误结果。

这就是我在中检查目录存在的方式

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

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);
}

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

            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();
}

但我只能创建一次目录。之后,当用户将文件上载到我们的应用程序的目录中时,我必须检查目录是否存在。那么,是否有其他方法可以这样做?@Srinivas当然,您只能创建一次。在此之后,您将得到一个错误。处理它。正如我上面所说的。是的,我明白了。谢谢,我不理解这个早期版本。现在很清楚了,谢谢。Af,因为我记得,
attrs
在找不到目录时不会为空。它抛出一个异常。@SRy:是的,但我在声明时为它指定了null,因此如果没有抛出异常
attrs
值将不会为null,我认为您的代码无法按预期工作。原因当在上述代码中引发异常时,如果不存在目录,则假设控制将转到
else
块,则控制不可能转到
If else
块。因此,您的代码仅在try-catch块下的“attrs=channelSftp.stat(currentDirectory+“/”+dir);”行中抛出
attrs
not nulException时有效。稍后,它将继续执行if-else部分。如果attrs值没有改变(为null),那么它将转到其他部分并创建目录。我认为异常是迫在眉睫的,它可以更具体一些:
试试{
`channel.stat(folderName);`}catch(SftpException e){`if(e.id==ChannelSftp.SSH_FX_NO_这样的文件){`channel mkdir(folderName);`}``else{`throw e;``}
}