【问题标题】:Using JSch, is there a way to tell if a remote file exists without doing an ls?使用 JSch,有没有办法在不执行 ls 的情况下判断远程文件是否存在?
【发布时间】:2013-07-15 07:34:22
【问题描述】:

使用 JSch,有没有一种方法可以判断远程文件是否存在,而无需执行 ls 并遍历文件以查找名称匹配?

谢谢

【问题讨论】:

    标签: java jsch


    【解决方案1】:

    你可以检查

     if [ -e FILE_NAME ] ; then
        //do something
     fi
    

    或

      if [ -d DIRNAME ]
    

    目录

    或

        if [ -l SYMLINK ]
    

    对于软链接

    希望对你有帮助


    这是在远程机器http://www.jcraft.com/jsch/examples/Exec.java.html上运行命令的示例

    您可以很好地运行ls 或传递整个脚本。相当于把脚本复制到远程机器上执行。

    【讨论】:

      【解决方案2】:

      (如果您使用的是库的 SFTP 部分,这是我没有考虑就做出的假设。)

      我认为它的ls(String path) 会接受文件名;我暂时无法查看。

      如果没有,则不需要手动迭代;您可以使用选择器变体:

      ls(String path, ChannelSftp.LsEntrySelector selector)
      

      【讨论】:

      • 如果文件不存在,这个调用会抛出异常,所以你需要Oleg Svechkarenko或zelinka提供的错误处理答案
      • 如果你使用文件的完整路径并且文件存在,你会得到一个元素的向量。如果文件不存在,您将获得com.jcraft.jsch.SftpException。 id=ChannelSftp.SSH_FX_NO_SUCH_FILE
      【解决方案3】:

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

      注意:与此问题无关,但有些人可能会觉得它有用。

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

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

      【讨论】:

      • 这是正确的解决方案,因为它会找到名称中带有“*”的文件 → 没有通配符!
      • 这至少是相关的,我专门来这里检查目录,而不是文件。我试图弄清楚传递给我的程序的参数是否引用了远程系统上的目录或文件,谢谢。
      【解决方案4】:

      你也可以这样做:

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

      如果你对不存在的东西执行 lstat,你会得到一个 id 为 2 的 SftpExecption,否则你会得到关于文件的信息。

      【讨论】:

      • if(e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) --> id 是从哪里来的?
      【解决方案5】:

      实际上在我的项目ls 中没有循环。我只是通过文件名传递给ls 调用路径。

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

      例如,有一个文件 file.txt,其 URL 为 sftp://user@www.server.comm/path/to/some/random/folder/file.txt。我传递给函数exists path 作为/path/to/some/random/folder/file.txt

      【讨论】:

      • 矢量!!久违了,我的老朋友。
      【解决方案6】:
      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;
      }
      

      }

      【讨论】:

      • 欢迎来到本站!像这样的答案在内容上可能很有用,但为所提供的代码提供某种解释或上下文总是有帮助的。我建议编辑您的答案,以更详细地解释您的代码的作用以及它如何解决问题。这对于将来的访问者看到您的答案很有用,因为他们可能不理解您的代码 sn-p,但可能更好地理解您的解释,或者您对代码 sn-p 的解释可以帮助他们解决他们遇到的类似问题。
      • 请进一步编辑此(更新)答案,按照@Catch44 先前评论中的建议进行解释
      猜你喜欢
      • 2022-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-12
      • 2011-04-15
      • 1970-01-01
      • 2012-02-19
      相关资源
      最近更新 更多