Wie überprüfe ich das Vorhandensein des Verzeichnisses, bevor ich ein neues Verzeichnis mit JSCH SFTP API erstelle? Ich versuche, lstat
zu verwenden, aber nicht sicher, dass es die Arbeit tut, die ich benötige. Danke im VorausWie überprüft man das Verzeichnis vor dem Erstellen eines neuen Verzeichnisses in JSCH?
Antwort
In Situationen wie diesem ist es immer besser, nur das Erschaffen zu machen und den Fehler zu behandeln. Auf diese Weise ist die Operation atomar und im Falle von SSH sparen Sie auch viel Netzwerkverkehr. Wenn Sie den Test zuerst durchführen, gibt es dann ein Zeitfenster, in dem sich die Situation ändern kann, und Sie müssen die Fehlerergebnisse trotzdem behandeln.
So überprüfe ich Verzeichnis Existenz in JSch.
Verzeichnis erstellen, wenn dir ont existiert
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);
}
Af für wie ich mich erinnere, dass 'attrs' nicht null sein wird, wenn es kein Verzeichnis findet. Es löst eine Ausnahme aus. – SRy
@SRy: Ja, aber ich habe ihm bei der Deklaration null zugewiesen. Wenn also die Ausnahme nicht ausgelöst wird, wäre der Wert "attrs" nicht null – abi1964
Ich glaube nicht, dass Ihr Code so funktioniert, wie Sie es erwartet haben. Wenn eine Ausnahme in den obigen Code geworfen wird, wenn kein Verzeichnis existiert, gehen Sie davon aus, dass die Kontrolle auf den Block "else" übergeht. Es besteht keine Chance, dass die Kontrolle in den Block "If-else" kommt. Ihr Code funktioniert also nur, wenn "attrs" nicht null ist – SRy
ich die gleiche Antwort hier im weiteren Kontext bin zu wiederholen. Die einzelnen Zeilen, um zu prüfen, ob das Verzeichnis existiert und ein neues Verzeichnis erstellen, sind
Hinweis. Die localChildFile.getName()
ist der Verzeichnisname, den Sie überprüfen möchten. Die gesamte Klasse ist unterhalb angehängt, die eine Datei oder den Inhalt eines Verzeichnisses rekursiv an den Remote-Server sendet.
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();
}
Aber ich kann das Verzeichnis nur eine time.After erstellen, dass, wenn der Benutzer die Datei auf unserer Anwendung lädt zu diesem Verzeichnis muss ich prüfen, ob Verzeichnis existed.So ist, gibt es jede alternative, das zu tun? – SRy
@Srinivas Natürlich können Sie es nur einmal erstellen. Danach erhalten Sie einen Fehler. Handle es. Wie ich oben sagte. – EJP
Ja, hab ich verstanden. Danke, dass ich das nicht verstanden habe. Jetzt ist es klar, danke. – SRy