Search code examples
javaclientsftpapache-sshd

A simple way to verify the existence of a file on the SFTP server in Java


I am writing an SFTP client using the Apache Mina SSHD library, specifically sshd-sftp 2.3.0. I chose it instead of the SSHJ library, because it is possible to write a String to a remote file directly, and there are also no unnecessary dependencies.

The task: when sending files to the SFTP server to make a backup copy of the previous file, if any.

I studied all the possibilities that the SftpClient class provides, and among them I did not find an easy way to search for a file.

  • There are listDir and readDir methods, they return Iterable <DirEntry>, but I suspect that with a large number of files they will work slowly.
  • We can simply force a file to be renamed using the rename method, but in my case there can be many backup files, and we must first find a free file name.

The current solution is to get the state of the file. If there is no such file, then a SftpException will be thrown, for example, "SFTP error (SSH_FX_NO_SUCH_FILE): No such file or directory". This message can be analyzed, and if the file is really not found, then just don't throw this exception further. Here is the code:

    private boolean fileExists(SftpClient sftpClient, String remoteDest) throws IOException {
        try {
            return null != sftpClient.stat(remoteDest);
        } catch (SftpException e) {
            if (e.getStatus() != SftpConstants.SSH_FX_NO_SUCH_FILE) {
                LOGGER.error("Error finding file {}", remoteDest);
                throw e;
            }
            return false;
        }
    }

The main problem is that this solution is ugly.

However, on the Internet I found only similar solutions using libraries JSch and Trilead SSH-2 for Java.

Perhaps there is another, simpler and more competent way to check for a file on an SFTP server?


Solution

  • That is the correct solution.

    SFTP protocol does not have a "does a file exist" query/request. The nearest equivalent is actually the "stat" query/request. So even if your favourite SFTP library had "does a file exist" method/API, it would internally do, what your code does.

    An equivalent in JSch: Using JSch, is there a way to tell if a remote file exists without doing an ls?