问题
Using JSch, is there a way to tell if a remote file exists without doing an ls and looping through the files to find a name match?
Thanks
回答1:
(This is if you're using the SFTP part of the library, an assumption I made without thinking about it.)
I thought its ls(String path) would accept filenames; I can't check at the moment.
If it doesn't, you don't need to iterate manually; you can use the selector variant:
ls(String path, ChannelSftp.LsEntrySelector selector)
回答2:
This is how I check directory existence in JSch.
Note: not related to this question, but some may find it useful.
Create directory if dir does not exist
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);
}
回答3:
You can also do something like this:
try {
channelSftp.lstat(name);
} catch (SftpException e){
if(e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE){
// file doesn't exist
} else {
// something else went wrong
throw e;
}
}
If you do an lstat on something that doesn't exist you get an SftpExecption with an id of 2, otherwise you get information about the file.
回答4:
Actually in my project ls working without loops. I just pass to the ls call path with filename.
private static boolean exists(ChannelSftp channelSftp, String path) {
Vector res = null;
try {
res = channelSftp.ls(path);
} catch (SftpException e) {
if (e.id == SSH_FX_NO_SUCH_FILE) {
return false;
}
log.error("Unexpected exception during ls files on sftp: [{}:{}]", e.id, e.getMessage());
}
return res != null && !res.isEmpty();
}
For example there a file file.txt with an url sftp://user@www.server.comm/path/to/some/random/folder/file.txt. I pass to function exists path as /path/to/some/random/folder/file.txt
回答5:
you can check by
if [ -e FILE_NAME ] ; then
//do something
fi
or
if [ -d DIRNAME ]
for directory
or
if [ -l SYMLINK ]
for softlinks
I hope this helps
Here is an example to run commands on remote machine http://www.jcraft.com/jsch/examples/Exec.java.html
You can very well run ls or a pass a whole script. It's same as copying the script to remote machine and then executing it.
回答6:
I saw -1 on my previous answer. Hope its wasn't clear for you to understand. Below is entire code for same functionality. Also let me know if you need any other information regarding this.
import java.util.ArrayList;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
public class FileExists {
ChannelExec channelExec = null;
static Channel channel = null;
static String host = "hostname";
static String user = "username";
static String password = "password$";
public static void main(String[] args) {
String filename = "abc.txt";
String filepath = "/home/toolinst/ggourav";
try {
Channel channel = getChannelSftp(host, user, password);
channel.connect();
ChannelSftp channelSftp = (ChannelSftp) channel;
channelSftp.cd(filepath);
String path = channelSftp.ls(filename).toString();
if (!path.contains(filename)) {
System.out.println("File doesn't exist.");
} else
System.out.println("File already exist.");
} catch (Exception e) {
e.printStackTrace();
}
}
private static Channel getChannelSftp(String host, String user, String password) {
try {
JSch jsch = new JSch();
Session session = jsch.getSession(user, host, 22);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
config.put("PreferredAuthentications", "publickey,keyboard-interactive,password");
session.setConfig(config);
session.setPassword(password);
session.connect();
channel = session.openChannel("sftp");
} catch (Exception e) {
System.out.println("Failed to get sftp channel. " + e);
}
return channel;
}
}
回答7:
import java.util.ArrayList;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
public class FileExists {
ChannelExec channelExec = null;
static Channel channel = null;
static String host = "hostname";
static String user = "username";
static String password = "password$";
public static void main(String[] args) {
String filename = "abc.txt";
String filepath = "/home/toolinst/ggourav";
try {
Channel channel = getChannelSftp(host, user, password);
channel.connect();
ChannelSftp channelSftp = (ChannelSftp) channel;
channelSftp.cd(filepath);
String path = channelSftp.ls(filename).toString();
if (!path.contains(filename)) {
System.out.println("File doesn't exist.");
} else
System.out.println("File already exist.");
} catch (Exception e) {
e.printStackTrace();
}
}
private static Channel getChannelSftp(String host, String user, String password) {
try {
JSch jsch = new JSch();
Session session = jsch.getSession(user, host, 22);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
config.put("PreferredAuthentications", "publickey,keyboard-interactive,password");
session.setConfig(config);
session.setPassword(password);
session.connect();
channel = session.openChannel("sftp");
} catch (Exception e) {
System.out.println("Failed to get sftp channel. " + e);
}
return channel;
}
}
来源:https://stackoverflow.com/questions/11968878/using-jsch-is-there-a-way-to-tell-if-a-remote-file-exists-without-doing-an-ls