Как получить все подкаталоги в каталоге, используя uribuilder - PullRequest
0 голосов
/ 18 июня 2019

Попытка создать UriBuilder, в котором будут перечислены все подкаталоги для последующего использования.

Я пробовал примеры от Microsoft для этого процесса и безуспешно пытался использовать метод directory.getdirectory.

String result = String.Empty;
Search searchResults = new Search();

try
{
    UriBuilder uriBuilder = new UriBuilder();
    uriBuilder.Scheme = "ftp";
    uriBuilder.Host = "ftp.myfilepath.com/public/doc";
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(uriBuilder.Uri);

    request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;

    FtpWebResponse response = (FtpWebResponse)request.GetResponse();

    Stream responseStream = response.GetResponseStream();
    StreamReader reader = new StreamReader(responseStream);
    Console.WriteLine(reader.ReadToEnd());

    Console.WriteLine($"Directory List Complete, status {response.StatusDescription}");

    reader.Close();
    response.Close();
    result = reader.ReadToEnd();

    if (result != null)
    {
        searchResults.Messages = result;
    }
}
catch (Exception ex)
{
    searchResults.Messages = "File not found.";
} 

Я хочу перечислить каталоги, найденные по пути, указанному UriBuilder.Результат всегда получается пустым, и я не понимаю, почему или чего мне не хватает.

1 Ответ

0 голосов
/ 18 июня 2019

Проблема

Несмотря на несколько синтаксических ошибок (отсутствует ключевое слово var или объявление типа в строках 18 и 22), ваш код работает правильно.Единственная проблема заключается в том, что вы звоните reader.ReadToEnd() дважды и, более того, второй вызов происходит сразу после того, как вы явно закрыли оба ResponseStream и StreamReader.

Первый вызов находится на линии 12, котораявыводит список каталогов на консоль:

Console.WriteLine(reader.ReadToEnd());

И второй вызов происходит в строке 18, где вы пытаетесь получить его возвращаемое значение в переменную result:

result = reader.ReadToEnd();

Но это только после того, как вы закрыли и ResponseStream, и StreamReader:

reader.Close();
response.Close();
result = reader.ReadToEnd();

Так вы даже получите сообщение об ошибке, объясняющее, что вы делаете неправильно:

Невозможно прочитать из закрытого TextReader.

Это исключение, выброшенное в строке 18.

Даже если вы переместите оба вызова в методы Close() послев строке 18 он все равно не будет работать, поскольку первый вызов метода reader.ReadToEnd() очищает буфер чтения и удаляет объект NetworkStream, поэтому в строке 18 будет выдано следующее исключение:

Невозможно получить доступ к удаленному объекту.Имя объекта: 'System.Net.Sockets.NetworkStream'.

Решение

Вам нужно только один раз вызвать метод reader.ReadToEnd(), прежде чем закрытьи ResponseStream, и StreamReader, и сохраните возвращаемое значение в переменной.Затем вы можете делать с результатом все, что захотите:

var uriBuilder = new UriBuilder();
uriBuilder.Scheme = "ftp";
uriBuilder.Host = "ftp.myfilepath.com/public/doc";
var request = (FtpWebRequest)WebRequest.Create(uriBuilder.Uri);

request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;

var response = (FtpWebResponse)request.GetResponse();

var responseStream = response.GetResponseStream();
var reader = new StreamReader(responseStream);
var result = reader.ReadToEnd();

Console.WriteLine(result);
Console.WriteLine($"Directory List Complete, status {response.StatusDescription}");

reader.Close();
response.Close();

Рабочий пример

Следующий код должен работать, если вы делаете все в точности так, как было предложено:

  1. создайте новое решение в Visual Studio, содержащее проект консольного приложения, используйте .NET Framework 4.7.2
  2. и введите следующий код в Program.cs:

    using System;
    using System.IO;
    using System.Net;
    
    namespace FtpDirectoryListing
    {
        class Program
        {
            static void Main(string[] args)
            {
                var uriBuilder = new UriBuilder();
                uriBuilder.Scheme = "ftp";
                uriBuilder.Host = "speedtest.tele2.net";
                var request = (FtpWebRequest)WebRequest.Create(uriBuilder.Uri);
    
                request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
    
                var response = (FtpWebResponse)request.GetResponse();
    
                var responseStream = response.GetResponseStream();
                var reader = new StreamReader(responseStream);
                var result = reader.ReadToEnd();
    
                Console.WriteLine(result);
                Console.WriteLine($"Directory List Complete, status {response.StatusDescription}");
    
                reader.Close();
                response.Close();
            }
        }
    }
    
  3. Запустите его

  4. Поделитесь с нами любыми потенциальными ошибками
...