C# FTP, how to check if a Path is a File or a Dire

2019-06-24 02:21发布

问题:

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.

回答1:

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



回答2:

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



回答3:

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.



回答4:

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;
}


回答5:

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.



回答6:

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.



回答7:

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.
    }
}


标签: c# file ftp