23

I have to read a bunch of .CSV files with dynamic file names from a SFTP server. These files get generated every 15 minutes.

I am using JSch's ChannelSftp, but there is no method which would give the exact filenames. I only see an .ls() method. This gives a Vector e.g.

[drwxr-xr-x    2 2019     2019          144 Aug  9 22:29 .,
 drwx------    6 2019     2019          176 Aug 27  2009 ..,
 -rw-r--r--    1 2019     2019          121 Aug  9 21:03 data_task1_2011_TEST.csv,
 -rw-r--r--    1 2019     2019          121 Aug  9 20:57 data_task1_20110809210007.csv]

Is there a simple way to read all the files in a directory and copy them to another location?

This code works for copying a single file:

JSch jsch = new JSch();
session = jsch.getSession(SFTPUSER,SFTPHOST,SFTPPORT);
session.setPassword(SFTPPASS);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
channel = session.openChannel("sftp");
channel.connect();
channelSftp = (ChannelSftp)channel;
channelSftp.cd(SFTPWORKINGDIR);
channelSftp.get("data_task1_20110809210007.csv","data_task1_20110809210007.csv");
Paŭlo Ebermann
  • 73,284
  • 20
  • 146
  • 210
pingu
  • 645
  • 3
  • 11
  • 21

2 Answers2

53

The ls method is the one you need. It returns a vector of LsEntry objects, each of which you can ask about its name.

So, after your channelSftp.cd(SFTPWORKINGDIR);, you could do the following:

Vector<ChannelSftp.LsEntry> list = channelSftp.ls("*.cvs");
for(ChannelSftp.LsEntry entry : list) {
    channelSftp.get(entry.getFilename(), destinationPath + entry.getFilename());
}

(This assumes destinationPath is a local directory name ending with / (or \ in Windows).)

Of course, if you don't want to download the same files again after 15 minutes, you might want to have a list of the local files, to compare them (use a HashSet or similar), or delete them from the server.

Paŭlo Ebermann
  • 73,284
  • 20
  • 146
  • 210
  • 2
    You were lucky I have `jsch` in [my observed tags](http://stackexchange.com/filters/19305/palos-filter), and where just checking some minutes after you posted :-). Glad to help. – Paŭlo Ebermann Aug 09 '11 at 23:44
  • @ides: I didn't use JSch for the last year, so I am not certain here. But I see no reason the API should have changed here incompatibly, so I suggest to simply try it. – Paŭlo Ebermann Apr 08 '13 at 07:50
  • can channelSftp.ls(path) search the full filename? no * or ? eg: channelSftp.ls("abc.cvs"); – littlecodefarmer758 Nov 07 '13 at 02:14
  • @user1687981 yes it can. the only restriction in the docs is that `wildcards (* or ?) [are] in the last component (i.e. after the last /)` – berbt Apr 28 '14 at 20:45
2

Note that ls is case sensitive. This method retrieves all csv files, regardless of the extension case

ArrayList<String> list = new ArrayList<String>();
Vector<LsEntry> entries = sftpChannel.ls("*.*");
for (LsEntry entry : entries) {
    if(entry.getFilename().toLowerCase().endsWith(".csv")) {
        list.add(entry.getFilename());
    }
}
berbt
  • 252
  • 2
  • 13