Получить информацию о файле FTP на основе даты и времени в C # - PullRequest
1 голос
/ 06 марта 2019

Вопрос: Я хочу получить сведения о файле с FTP-сервера на основе определенной даты и времени без использования какой-либо третьей стороны.

Проблема: Мой FTP-сервер содержит 1000 файлов, поэтому для получения всех файлов и после этой фильтрации требуется время.

Есть ли более быстрый способ сделать это?

string ftpPath = "ftp://directory/";

// Some expression to match against the files...do they have a consistent 
// name? This example would find XML files that had 'some_string' in the file 

Regex matchExpression = new Regex("^test.+\.xml$", RegexOptions.IgnoreCase);

// DateFilter
DateTime cutOff = DateTime.Now.AddDays(-10);

List<ftplineresult> results = FTPHelper.GetFilesListSortedByDate(ftpPath, matchExpression, cutOff);
public static List<FTPLineResult> GetFilesListSortedByDate(string ftpPath, Regex nameRegex, DateTime cutoff)
{
    List<FTPLineResult> output = new List<FTPLineResult>();
    FtpWebRequest request = FtpWebRequest.Create(ftpPath) as FtpWebRequest;
    ConfigureProxy(request);
    request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
    FtpWebResponse response = request.GetResponse() as FtpWebResponse;
    StreamReader directoryReader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.ASCII);
    var parser = new FTPLineParser();
    while (!directoryReader.EndOfStream)
    {
        var result = parser.Parse(directoryReader.ReadLine());
        if (!result.IsDirectory && result.DateTime > cutoff && nameRegex.IsMatch(result.Name))
        {
            output.Add(result);
        }
    }
    // need to ensure the files are sorted in ascending date order
    output.Sort(
        new Comparison<FTPLineResult>(
            delegate(FTPLineResult res1, FTPLineResult res2)
            {
                return res1.DateTime.CompareTo(res2.DateTime);
            }
        )
    );
    return output;
}

Ответы [ 2 ]

2 голосов
/ 06 марта 2019

Проблема: мой FTP-сервер содержит 1000 файлов, поэтому получение всех файлов и после этой фильтрации занимает время.

Есть ли более быстрый способ сделать это?

Нет .


Единственный стандартный FTP API - это команда LIST и ее компаньоны.Все это даст вам список всех файлов в папке.Там нет FTP API, чтобы дать вам файлы, отфильтрованные по отметке времени.

Некоторые серверы поддерживают нестандартные маски файлов в команде LIST.
Таким образом, их заполнение позволяет возвращать только файлы *.xml.
См. Как получить список файлов на основе сопоставления с шаблоном по FTP?


Подобные вопросы:

0 голосов
/ 16 марта 2019

У меня есть альтернативное решение для выполнения моих функций с использованием FluentFTP.

Пояснение:

Я загружаю файлы с FTP (требуется разрешение на чтение) с той же структурой папок.

Таким образом, каждый раз, когда выполняется задание / служба, я могу проверить по физическому пути, существует ли один и тот же файл (полный путь). Если его нет, его можно рассматривать как новый файл. И я могу сделать то же самое и скачать тоже.

Это просто альтернативное решение.

Изменения кода:

 private static void GetFiles()
 {
    using (FtpClient conn = new FtpClient())
    {
        string ftpPath = "ftp://myftp/";

        string downloadFileName = @"C:\temp\FTPTest\";

        downloadFileName +=  "\\";

        conn.Host = ftpPath;
        //conn.Credentials = new NetworkCredential("ftptest", "ftptest");
        conn.Connect();

        //Get all directories

        foreach (FtpListItem item in conn.GetListing(conn.GetWorkingDirectory(),
            FtpListOption.Modify | FtpListOption.Recursive))
        {
            // if this is a file
            if (item.Type == FtpFileSystemObjectType.File)
            {
                string localFilePath = downloadFileName + item.FullName;

                //Only newly created files will be downloaded.
                if (!File.Exists(localFilePath))
                {
                    conn.DownloadFile(localFilePath, item.FullName);
                    //Do any action here.
                    Console.WriteLine(item.FullName);
                }
            }
        }
    }
}
...