Ruby FTP Separating files from Folders

You can avoid recursion if you list all files at once

files = ftp.nlst('**/*.*')

Directories are not included in the list but the full ftp path is still available in the name.

EDIT

I'm assuming that each file name contains a dot and directory names don't. Thanks for mentioning @Niklas B.


There are a huge variety of FTP servers around.

We have clients who use some obscure proprietary, Windows-based servers and the file listing returned by them look completely different from Linux versions.

So what I ended up doing is for each file/directory entry I try changing directory into it and if this doesn't work - consider it a file :)

The following method is "bullet proof":

# Checks if the give file_name is actually a file.
def is_ftp_file?(ftp, file_name)
  ftp.chdir(file_name)
  ftp.chdir('..')
  false
rescue
  true
end

file_names = ftp.nlst.select {|fname| is_ftp_file?(ftp, fname)}

Works like a charm, but please note: if the FTP directory has tons of files in it - this method takes a while to traverse all of them.


You can also use a regular expression. I put one together. Please verify if it works for you as well as I don't know it your dir listing look different. You have to use Ruby 1.9 btw.

reg = /^(?<type>.{1})(?<mode>\S+)\s+(?<number>\d+)\s+(?<owner>\S+)\s+(?<group>\S+)\s+(?<size>\d+)\s+(?<mod_time>.{12})\s+(?<path>.+)$/

match = entry.match(reg)

You are able to access the elements by name then

match[:type] contains a 'd' if it's a directory, a space if it's a file.

All the other elements are there as well. Most importantly match[:path].

Tags:

Ruby

Ftp