0

I'm trying to check the existance of a file in an FTP server using Spring Integration but it doesn't seem to work. It works fine with directories but not with files. In documentation is mentioned that works with directories and files. Am I building the path correctly?

private DefaultFtpSessionFactory getFTPFactory() {
    DefaultFtpSessionFactory defaultFtpSessionFactory = new DefaultFtpSessionFactory();
    defaultFtpSessionFactory.setHost("localhost");
    defaultFtpSessionFactory.setPort(21);
    defaultFtpSessionFactory.setUsername("foo");
    defaultFtpSessionFactory.setPassword("pass");

    return defaultFtpSessionFactory;
  }




public boolean getFTPFiles() throws IOException {
    DefaultFtpSessionFactory defaultFtpSessionFactory = getFTPFactory();
    FtpSession ftpSession = defaultFtpSessionFactory.getSession();
    FTPClient clientInstance = ftpSession.getClientInstance();
    clientInstance.enterLocalPassiveMode();

    return ftpSession.exists("/ftp/foo/study/download/test_1.txt");
  }
KrisKris1
  • 189
  • 3
  • 17

1 Answers1

0

We don't know if you path is correct. The logic in the FtpSession.exists() is like this:

public boolean exists(String path) throws IOException {
    Assert.hasText(path, "'path' must not be empty");

    String[] names = this.client.listNames(path);
    boolean exists = !ObjectUtils.isEmpty(names);

    if (!exists) {
        String currentWorkingPath = this.client.printWorkingDirectory();
        Assert.state(currentWorkingPath != null,
                "working directory cannot be determined; exists check can not be completed");

        try {
            exists = this.client.changeWorkingDirectory(path);
        }
        finally {
            this.client.changeWorkingDirectory(currentWorkingPath);
        }

    }

    return exists;
}

So, it tries to list the provided path in the user working dir. If not it tries to switch a working dir to the provided path, which is not going to work for file name apparently...

I can suggest to try with the FtpRemoteFileTemplate.exists(). See its JavaDocs:

/**
 * This particular FTP implementation is based on the {@link FTPClient#getStatus(String)}
 * by default, but since not all FTP servers properly implement the {@code STAT} command,
 * the framework internal {@link FtpRemoteFileTemplate} instances are switched to the
 * {@link FTPClient#listNames(String)} for only files operations.
 * <p> The mode can be switched with the {@link #setExistsMode(ExistsMode)} property.
 * <p> Any custom implementation can be done in an extension of the {@link FtpRemoteFileTemplate}.
 * @param path the remote file path to check.
 * @return true or false if remote file exists or not.
 */
@Override
public boolean exists(final String path) {

I'm not sure about localPassive/ActiveMode...

Maybe there is a way to investigate a server logs to determine the issue why it doesn't let you to see that file?

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • Actually the server allows me to see that file. If I do ftpSession.list("/ftp/foo/study/download") I can actually see the file in the FTPFile[] that I get back. I also can read the file using the ftpSession.read("/ftp/foo/study/download/test_1.txt", dummyStream). It's just that exists is not working which is strange. – KrisKris1 Apr 09 '21 at 14:11
  • As I said: see `FtpRemoteFileTemplate.exists()` JavaDocs. Not all FTP servers allows to get a files via `NLST` command. – Artem Bilan Apr 09 '21 at 14:16