Check if is file or folder on FTP

Raskolnikov

I read list of files/folders from FTP.

Problem is that I don't know if is file or folder. Currently I am checking if string have extension. If yes than it is file else it is folder. But this is not good enough, it can exist file without extension and folder with extension (eg. folder name could be FolderName.TXT)

This is code I use to list content of folder:

public async Task<CollectionResult<string>> ListFolder(string path)
{
    try
    {
        FtpWebRequest ftpRequest = null;
        var fileNames = new List<string>();
        var res = new CollectionResult<string>();
        ftpRequest = ftpBuilder.Create(path, WebRequestMethods.Ftp.ListDirectory);
        using (var ftpResponse = (FtpWebResponse)await ftpRequest.GetResponseAsync())
        using (var ftpStream = ftpResponse.GetResponseStream())
        using (var streamReader = new StreamReader(ftpStream, Encoding.UTF8))
        {
            string fileName = streamReader.ReadLine();
            while (!string.IsNullOrEmpty(fileName))
            {
                fileNames.Add(Path.Combine(path, fileName.Substring(fileName.IndexOf('/') + 1, fileName.Length - fileName.IndexOf('/') - 1)));
                fileName = streamReader.ReadLine();
            }
        }
        ftpRequest = null;
        res.ListResult = fileNames;
        return res;
    }
    catch (Exception e)
    {
        e.AddExceptionParameter(this, nameof(path), path);
        throw;
    }
}

It would be best if I could detect if is file or folder inside while loop, but it is not possible to do this just from string.

Thank you for your help.


EDIT

I found similar question. C# FTP, how to check if a Path is a File or a Directory? But question is very old and there is no nice solution.


Edit: Solution

 public async Task<CollectionResult<Tuple<string, bool>>> ListFolder(string path)
        {
            try
            {
                FtpWebRequest ftpRequest = null;
                var fileNames = new CollectionResult<Tuple<string, bool>>();
                fileNames.ListResult = new List<Tuple<string, bool>>();
                if (!(IsFtpDirectoryExist(path)))
                {
                    throw new RemoteManagerWarningException(ErrorKey.LIST_DIRECTORY_ERROR, fileNames.ErrorMessage = $"path folder {path} not exists");
                }
                ftpRequest = ftpBuilder.Create(path, WebRequestMethods.Ftp.ListDirectoryDetails);
                using (var ftpResponse = (FtpWebResponse)await ftpRequest.GetResponseAsync())
                using (var ftpStream = ftpResponse.GetResponseStream())
                using (var streamReader = new StreamReader(ftpStream, Encoding.UTF8))
                {
                    while (!streamReader.EndOfStream)
                    {
                        string line = streamReader.ReadLine();
                        string[] tokens = line.Split(new[] { ' ' }, 9, StringSplitOptions.RemoveEmptyEntries);
                        // is number:
                        Regex rgx = new Regex(@"^[\d\.]+$");
                        var isExternalFtpOrUnixDirectoryStyle = !(rgx.IsMatch(line[0].ToString()));
                        string name = string.Empty;
                        bool isFolder = false;

                        if (isExternalFtpOrUnixDirectoryStyle)
                        {
                            name = tokens[8];
                            var permissions = tokens[0];
                            isFolder = permissions[0] == 'd';
                        }
                        else
                        {
                            tokens = line.Split(new[] { ' ' }, 4, StringSplitOptions.RemoveEmptyEntries);
                            name = tokens[3];
                            isFolder = tokens[2] == "<DIR>";
                        }
                        name = Path.Combine(path, name);
                        Tuple<string, bool> tuple = new Tuple<string, bool>(name, isFolder);
                        fileNames.ListResult.Add(tuple);                           
                    }
                }
                ftpRequest = null;
                return fileNames;
            }
            catch (Exception e)
            {
                e.AddExceptionParameter(this, nameof(path), path);
                throw;
            }
        }
Martin Prikryl

There's no way to identify if a directory entry is a sub-directory of file in a portable way with the FtpWebRequest or any other built-in feature of .NET framework. The FtpWebRequest unfortunately does not support the MLSD command, which is the only portable way to retrieve directory listing with file attributes in FTP protocol. See also Checking if object on FTP server is file or directory.

Your options are:

  • Do an operation on a file name that is certain to fail for a file and succeeds for a directory (or vice versa). I.e. you can try to download the "name". If that succeeds, it's a file, if that fails, it's a directory.
  • You may be lucky and in your specific case, you can tell a file from a directory by a file name (i.e. all your files have an extension, while subdirectories do not)
  • You use a long directory listing (LIST command = ListDirectoryDetails method) and try to parse a server-specific listing. Many FTP servers use *nix-style listing, where you identify a directory by the d at the very beginning of the entry. But many servers use a different format.

    For some examples of implementing the parsing, see:
    *nix format: Parsing FtpWebRequest ListDirectoryDetails line
    DOS/Windows format: C# class to parse WebRequestMethods.Ftp.ListDirectoryDetails FTP response


If you want to avoid troubles with parsing the server-specific directory listing formats, use a 3rd party library that supports the MLSD command and/or parsing various LIST listing formats; and recursive downloads.

For example with WinSCP .NET assembly you can use Sesssion.ListDirectory:

// Setup session options
SessionOptions sessionOptions = new SessionOptions
{
    Protocol = Protocol.Ftp,
    HostName = "example.com",
    UserName = "user",
    Password = "mypassword",
};

using (Session session = new Session())
{
    // Connect
    session.Open(sessionOptions);

    RemoteDirectoryInfo directory = session.ListDirectory("/home/martin/public_html");

    foreach (RemoteFileInfo fileInfo in directory.Files)
    {
        if (fileInfo.IsDirectory)
        {
            // directory
        }
        else
        {
            // file
        }
    }
}

Internally, WinSCP uses the MLSD command, if supported by the server. If not, it uses the LIST command and supports dozens of different listing formats.

(I'm the author of WinSCP)

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Check if FTP entry is file or folder with PHP

From Dev

how to check if file exist in a folder on ftp in c#

From Dev

Check if FTP folder exists & if not then create it

From Dev

Check if FTP folder exists & if not then create it

From Dev

Move file to parent folder on FTP

From Dev

Deleting a file and a folder in a FTP folder, using VBA

From Dev

Check if file exists in a folder

From Dev

Check if input is a file or folder

From Dev

ICS FTP - Function to check if folder exists on the ftp server

From Dev

Get the latest updated file from FTP Folder

From Dev

Uploading file to FTP server in a particular folder location

From Dev

Batch file - Download the latest FTP folder

From Dev

Get the latest updated file from FTP Folder

From Dev

Download a file from ftp and save in the same folder

From Dev

Batch file - Download the latest FTP folder

From Dev

Qt: check if a file in folder is changed

From Dev

Check Multiple File Exist in folder

From Dev

check if file exists in project folder

From Dev

check existence of ftp file and parse exit code

From Dev

How to move CSV file in FTP server one folder to another?

From Dev

Upload a ZIP file and UNZIP ftp folder via PHP

From Dev

Check if file exists on FTP - Don't know the name of the file

From Dev

Check if file exists on FTP - Don't know the name of the file

From Dev

php FTP file: How can check if a file is open by another process

From Dev

Check if file or folder by given path exists

From Dev

Check a file path belong to folder name

From Dev

How to check a path is a file or folder in PHP

From Dev

Check if an HTML file is online or local folder

From Dev

Check if a folder has a certain type of file present

Related Related

HotTag

Archive