6

I have an array that contains some FTP pathes, like follows:

"ftp//ip/directory/directory1",
"ftp//ip/directory/directory2",
"ftp//ip/directory/file.txt",
"ftp//ip/directory/directory3",
"ftp//ip/directory/another_file.csv"

How can i find out if the path is a file or a directory?

Thanks in advance.

Chamchamal
  • 61
  • 1
  • 1
  • 2
  • Do you have access to the server? And if so, how? This question lacks many details. – Dykam Nov 10 '11 at 21:36
  • 1
    There is no way to tell just by the path. – Oded Nov 10 '11 at 21:37
  • If you don't have access to the server, a simple regex checking if the path has an extension (i.e. .xxx) is a feeble, but reasonable way to go... – Didaxis Nov 10 '11 at 21:39
  • 2
    The only accurate way is to connect to the FTP server and ask it. It is the only one that'll know as files are not required to have file extensions. Not to mention that it's also possible for directories to have periods in them. – Johannes Kommer Nov 10 '11 at 21:41
  • The question is very old, but for anyone that needs an answer to this, the best chance is to use regex and ListDirectoryDetails. The whole implementation here: [http://blogs.msdn.com/b/adarshk/archive/2004/09/15/sample-code-for-parsing-ftpwebrequest-response-for-listdirectorydetails.aspx](http://blogs.msdn.com/b/adarshk/archive/2004/09/15/sample-code-for-parsing-ftpwebrequest-response-for-listdirectorydetails.aspx) – netadictos Dec 23 '15 at 00:58

7 Answers7

5

Use the LIST command, which you can refer to RFC959, to get the details about items under the specified path. Take FileZilla Server for example, the LIST command will return standard LINUX permission format which you can find here. The first letter indicates if the requested path is file or directory. Also a simple library written in C# can be found here

hugh
  • 63
  • 1
  • 3
5

I had the same problem. I worked off of hughs answer. You need to make an FTPRequest like:

request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;

grab it from streamreader and stick it in a string

StreamReader reader = new StreamReader(responseStream);

            string directoryRaw = null;

            try { while (reader.Peek() != -1) { directoryRaw +=    reader.ReadLine() + "|"; } }
            catch (Exception ex) { Console.WriteLine(ex.ToString()); }

when you print this it is going to look like:

|-rw-r--r-- 1 user user 1699 Jun 1 2015 404.shtml

|drwxr-xr-x 2 user user 4096 Sep 8 19:39 cgi-bin

|drwxr-xr-x 2 user user 4096 Nov 3 10:52 css

These are seperated by | so that will be the delim for a splitstring

if it starts with a d and not a - then its a directory, else its a file.

these are all the same size before file name so make a new string for each of these strings starting at position 62 to end and that will be the file name.

Hope it helps

Matthew Verstraete
  • 6,335
  • 22
  • 67
  • 123
user7380497
  • 51
  • 1
  • 3
4

There's no direct way.

Indirectly you could assume that filenames that have no period "." are directories, but that is not going to always be true.

Best is to write the code that consumes these paths carefully so it e.g. treats the path as a directory, then if the FTP server reports an error, treat it as a file.

Jeremy McGee
  • 24,842
  • 10
  • 63
  • 95
2

One way to do it is if we can assume that all files will end in an extension and all directories will not have an extension, we can use the System.IO.Path.GetExtension() method like this:

public bool IsDirectory(string directory)
{
    if(directory == null)
    {
        throw new ArgumentNullException(); // or however you want to handle null values
    }

    // GetExtension(string) returns string.Empty when no extension found
    return System.IO.Path.GetExtension(directory) == string.Empty;
}
Andrew Keller
  • 3,198
  • 5
  • 36
  • 51
0

I have found "hack" how to determine target type. If you will use

request.Method = WebRequestMethods.Ftp.GetFileSize;

on a folder, it will result in Exception

Unhandled Exception: System.Net.WebException: The remote server returned an erro r: (550) File unavailable (e.g., file not found, no access).

But using it on file, it will naturally return its size.

I have create sample code for such method.

    static bool IsFile(string ftpPath)
    {
        var request = (FtpWebRequest)WebRequest.Create(ftpPath);
        request.Method = WebRequestMethods.Ftp.GetFileSize;

        request.Credentials = new NetworkCredential("foo", "bar");
        try
        {
            using (var response = (FtpWebResponse)request.GetResponse())
            using (var responseStream = response.GetResponseStream())
            {
                return true;
            }
        }
        catch(WebException ex)
        {
            return false;
        }
    }

You might want to alter it, because this one will catch any FTP error.

Meyhem
  • 11
  • 1
  • 2
0

I had the same problem so I used GetFileSize to check if it's a File or Directory

var isFile = FtpHelper.IsFile("ftpURL", "userName", "password");

using System;
using System.Net;

public static class FtpHelper
{
    public static bool IsFile(Uri requestUri, NetworkCredential networkCredential)
    {
        return GetFtpFileSize(requestUri, networkCredential) != default(long); //It's a Directory if it has no size
    }
    public static FtpWebRequest GetFtpWebRequest(Uri requestUri, NetworkCredential networkCredential, string method = null)
    {
        var ftpWebRequest = (FtpWebRequest)WebRequest.Create(requestUri); //Create FtpWebRequest with given Request Uri.
        ftpWebRequest.Credentials = networkCredential; //Set the Credentials of current FtpWebRequest.

        if (!string.IsNullOrEmpty(method))
            ftpWebRequest.Method = method; //Set the Method of FtpWebRequest incase it has a value.
        return ftpWebRequest; //Return the configured FtpWebRequest.
    }
    public static long GetFtpFileSize(Uri requestUri, NetworkCredential networkCredential)
    {
        //Create ftpWebRequest object with given options to get the File Size. 
        var ftpWebRequest = GetFtpWebRequest(requestUri, networkCredential, WebRequestMethods.Ftp.GetFileSize);

        try { return ((FtpWebResponse)ftpWebRequest.GetResponse()).ContentLength; } //Incase of success it'll return the File Size.
        catch (Exception) { return default(long); } //Incase of fail it'll return default value to check it later.
    }
}
BenSabry
  • 483
  • 4
  • 10
0

You can use System.IO.Path.GetExtension(path)` as a way to check if your path has a file extension.

Given "ftp//ip/directory/directory1" or "ftp//ip/directory/directory2/", GetExtension will return a String.Empty to you.

This isn't foolproof, and it's possible though if there was a file without an extension that this would break down completely, or a directory with a period in it could cause issues.

Doozer Blake
  • 7,677
  • 2
  • 29
  • 40
  • Thanks for your answers. I just want to let you know that I have alot of files without extensions on the FTP server. – Chamchamal Nov 11 '11 at 07:25