Come verificare l'esistenza della directory prima di creare una nuova directory utilizzando l'API SFTP di JSCH? Sto cercando di utilizzare lstat
ma non sono sicuro che stia facendo il lavoro di cui ho bisogno.Grazie anticipatamenteCome verificare la directory esistente prima di creare una nuova directory in JSCH
risposta
In situazioni come questa è sempre meglio fare semplicemente la creazione e gestire l'errore. In questo modo l'operazione è atomica e, nel caso di SSH, si risparmia anche molto traffico di rete. Se esegui il test per primo, c'è una finestra temporale in cui la situazione può cambiare e devi comunque gestire i risultati dell'errore.
Ecco come controllo la presenza della directory in JSch.
creare la directory se non dir ont esistono
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 per come ricordo che 'attrs' non sarà nullo quando non trova una directory. Genera un'eccezione. – SRy
@SRy: sì ma ho assegnato null ad esso mentre dichiaro, quindi se l'eccezione non viene lanciata il valore di 'attrs' non sarebbe nullo – abi1964
Non penso che il tuo codice funzioni come previsto. Causa quando viene lanciata un'eccezione nel codice precedente quando non esiste alcuna directory, supponendo che il controllo arriverà al blocco 'else', non vi è alcuna possibilità che il controllo arrivi al blocco 'If-else'. Quindi il tuo codice funziona solo quando 'attrs' non è nulla – SRy
ripeto la stessa risposta qui nel contesto più ampio. Le linee particolari per verificare se esiste la directory e fare una nuova directory è
SftpATTRS attrs;
try {
attrs = channel.stat(localChildFile.getName());
}catch (Exception e) {
channel.mkdir(localChildFile.getName());
}
Nota. il localChildFile.getName()
è il nome della directory che si desidera controllare. L'intera classe è allegata di seguito che invia un file o il contenuto di una directory in modo ricorsivo al server remoto.
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();
}
Ma posso creare la directory sola time.After che quando l'utente carica il file alla nostra applicazione a quella directory devo verificare se directory è existed.So, c'è qualche alternativo per farlo? – SRy
@Srinivas Ovviamente puoi crearlo solo una volta. Dopo ciò avrai un errore. Occupatene. Come ho detto sopra. – EJP
Sì, ho capito. Grazie, non ho capito il mio orecchio. Ora è chiaro, grazie. – SRy