How to get the last-modified date of files on FTP server

Marco Dinatsoli picture Marco Dinatsoli · Dec 22, 2014 · Viewed 17k times · Source

This is my code

FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(FTPAddress);
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse();
StreamReader streamReader = new StreamReader(response.GetResponseStream());

List<string> directories = new List<string>();

string line = streamReader.ReadLine();
while (!string.IsNullOrEmpty(line))
{
    directories.Add(line);
    line = streamReader.ReadLine();
}

As you see, I am using ListDirectoryDetails.

For every line in the directories, this is the content:

ftp://172.28.4.7//12-22-14  01:21PM                 9075 fileName.xml

My question is how to get the time from that line? Should I parse the string? I don't think so because I read that there is the LastModified property, but I don't know how to use it.

Could you help me please?

Answer

Martin Prikryl picture Martin Prikryl · Jul 11, 2017

Unfortunately, there's no really reliable and efficient way to retrieve modification timestamp of all files in a directory using features offered by .NET framework, as it does not support the FTP MLSD command. The MLSD command provides a listing of remote directory in a standardized machine-readable format. The command and the format is standardized by RFC 3659.

Alternatives you can use, that are supported by .NET framework:

  • ListDirectoryDetails method (the FTP LIST command) to retrieve details of all files in a directory and then you deal with FTP server specific format of the details

    DOS/Windows format: C# class to parse WebRequestMethods.Ftp.ListDirectoryDetails FTP response
    *nix format: Parsing FtpWebRequest ListDirectoryDetails line

  • GetDateTimestamp method (the FTP MDTM command) to individually retrieve timestamps for each file. An advantage is that the response is standardized by RFC 3659 to YYYYMMDDHHMMSS[.sss]. A disadvantage is that you have to send a separate request for each file, what can be quite inefficient. This method uses the LastModified property that you mention:

    const string uri = "ftp://example.com/remote/path/file.txt";
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(uri);
    request.Method = WebRequestMethods.Ftp.GetDateTimestamp;
    FtpWebResponse response = (FtpWebResponse)request.GetResponse();
    Console.WriteLine("{0} {1}", uri, response.LastModified);
    

Alternatively you can use a 3rd party FTP client implementation that supports the modern MLSD command.

For example WinSCP .NET assembly supports that.

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

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

    // Get list of files in the directory
    string remotePath = "/remote/path/";
    RemoteDirectoryInfo directoryInfo = session.ListDirectory(remotePath);

    foreach (RemoteFileInfo fileInfo in directoryInfo.Files)
    {
        Console.WriteLine("{0} {1}", fileInfo.Name, fileInfo.LastWriteTime);
    }    
}

(I'm the author of WinSCP)