如何在使用JSCH SFTP API创建新目录之前检查目录是否存在?我正在尝试使用lstat
,但不确定它是否正在完成我需要的工作。谢谢提前
答案 0 :(得分:13)
这就是我在JSch中检查目录存在的方法。
如果dir存在,则创建目录
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);
}
答案 1 :(得分:7)
在这种情况下,最好只创建并处理错误。这样操作就是原子操作,而在SSH的情况下,你也节省了大量的网络流量。如果你先进行测试,那么就会有一个时间窗口,在此期间情况可能会发生变化,你必须处理错误结果。
答案 2 :(得分:1)
我在更广泛的背景下重复相同的答案。检查目录是否存在并创建新目录的特定行是
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();
}