Поток. Расположить или stream=null?

От RFC 3986 :

URI А может быть далее классифицирован как локатор, имя или оба. Термин "Унифицированный указатель ресурсов" (URL) относится к подмножеству URIs, которые, в дополнение к идентификации ресурса, обеспечивают средство определения местоположения ресурса путем описания его основного механизма доступа (например, его сетевое "местоположение"). Термин "Унифицированное имя ресурса" (УРНА) был использован исторически для обращения и к URIs в соответствии со схемой [RFC2141] "урны", которые требуются, чтобы оставаться глобально уникальными и персистентными, даже когда ресурс прекращает существование или становится недоступным, и к любому другому URI со свойствами имени.

, Таким образом, все URL являются URIs (на самом деле не совсем - видят ниже), и все УРНЫ являются URIs - но УРНЫ и URL отличаются, таким образом, Вы не можете сказать, что всеми URIs являются URL.

РЕДАКТИРОВАНИЕ: Я ранее думал, что все URL являются допустимым URIs, но согласно комментариям:

Не "все URL являются URIs". Это зависит от интерпретации RFC. Например, в Java синтаксическому анализатору URI не нравится [ или ], и поэтому спецификация говорит, "не должен", и не "не буду".

Так, чтобы пачкал воды далее, к сожалению.

, Если бы Вы уже не читали ответ Roger Pate , я советовал бы делать так также.

11
задан Henk Holterman 23 September 2009 в 19:28
поделиться

11 ответов

It ' s почти всегда ошибочно устанавливать для локальных переменных значение null, если только вы не захотите использовать это значение позже. Он не вызывает принудительную сборку мусора раньше - если вы не собираетесь читать из переменной позже, сборщик мусора может игнорировать ссылку (когда не в режиме отладки).

Однако почти всегда правильно закрывать потоки - в идеале в операторе using для простоты.

Это также почти всегда неправильно иметь такой голый блок "catch". Вы действительно хотите обработать что-нибудь , идущее не так, в том числе такие вещи, как OutOfMemoryException ?

Я бы переписал ваш код следующим образом:

HttpWebRequest req = (HttpWebRequest) WebRequest.Create("someUrl"));
req.Credentials = CredentialCache.DefaultCredentials;
req.Method = "GET";

using (WebResponse response = req.GetResponse())
{
    using (StreamReader reader = new StreamReader(response.GetResponseStream(),
                                                  Encoding.Default))
    {
        return reader.ReadToEnd();
    }
}

Теперь, если что-то пойдет не так, исключение будет передается вызывающему. Возможно, вам захочется поймать несколько конкретных исключений, но это ' Как правило, не рекомендуется представлять ошибки с помощью значения, которое могло бы быть допустимым «нормальным» ответом.

Наконец, действительно ли вы уверены, что хотите Encoding.Default ? Это кодировка по умолчанию для локального компьютера - обычно вам нужна кодировка, указанная в самом ответе.

28
ответ дан 3 December 2019 в 00:38
поделиться

Он должен иметь с использованием [который вызывает Dispose () ].

27
ответ дан 3 December 2019 в 00:38
поделиться

Да, Dispose () их.

Еще лучше сделать что-то вроде

using (HttpWebResponse response = (HttpWebResponse)req.GetResponse() )
using (Stream receiveStream = response.GetResponseStream() )
using (readStream = new StreamReader(receiveStream, Encoding.Default) )
{
   return readStream.ReadToEnd();
}

A using (x) Блок {} будет перезаписан (компилятором )
как try {} finally {x.Dispose ();}

Обратите внимание, что WebRequest не является IDisposable.

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

using (var client = new System.Net.WebClient())
{
    client.Encoding = ...;
    client.Credentials = ...;
    return client.DownloadString("SomeUrl");
}
9
ответ дан 3 December 2019 в 00:38
поделиться

Да. Практически все, что реализует метод Dispose (), должно иметь вызываемый метод Dispose (). Вы можете неявно вызвать его с помощью оператора using:

using(StreamReader stream = GetStream())
{
   stream.DoStuff();
}
8
ответ дан 3 December 2019 в 00:38
поделиться

Да.

Когда вы установлено значение null, он обнуляет только ссылку. Он не запускает никакого кода очистки, написанного создателем класса Stream.

Вы также можете рассмотреть оператор using () {} , который обрабатывает это за вас для типов IDisposable.

Пример:

using (MyDisposableObject mdo = new MyDisposableObject)
{
   // Do some stuff with mdo
   // mdo will automatically get disposed by the using clause
}
4
ответ дан 3 December 2019 в 00:38
поделиться

Нет, вам следует позвонить в Dispose или Close

2
ответ дан 3 December 2019 в 00:38
поделиться

Самый безопасный метод:

try {
    HttpWebRequest request = (HttpWebRequest) WebRequest.Create("someUrl");
    request.Credentials = CredentialCache.DefaultCredentials;
    request.Method = "GET";
    using (HttpWebResponse response = (HttpWebResponse) request.GetResponse()) {
        using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.Default)) {
            return reader.ReadToEnd();
        }
    }
} catch {
    return "Error";
}

Нет необходимости явно удалять поток response.GetResponseStream () , потому что присоединенный StreamReader удалит его для вы.

РЕДАКТИРОВАТЬ: Я согласен с другими ответами - перехват таких исключений - очень плохая практика. Я просто оставил это для сравнения. : -)

2
ответ дан 3 December 2019 в 00:38
поделиться

Да - вы должны явно вызывать Dispose () для классов, реализующих IDisposable, после того, как вы их использовали - это гарантирует, что все их ресурсы будут своевременно очищены. Оборачивание переменной в с помощью () делает то же самое (добавляя код упаковки, вызывающий за вас Dispose):

using (StreamReader reader = new StreamReader()) {
    // do stuff with reader
}
1
ответ дан 3 December 2019 в 00:38
поделиться

В библиотеках .net есть несколько ошибок. Stream - это одно, а другое - большая часть Imaging API. Эти сущности, которые используют определенные системные ресурсы, не собирают мусор прикрепленные системные ресурсы.

Если что-то использует IDisposable API, лучше всего заключить это в блок using, как люди указали выше.

Читайте "использование" и помните об этом, когда имеете дело с дескрипторами файлов или изображениями.

0
ответ дан 3 December 2019 в 00:38
поделиться

На самом деле, на вопрос был дан ответ, но я хочу уточнить одну вещь.

Каждый раз, когда объект реализует интерфейс IDisposable , вы должны избавиться от него с помощью метода Dispose или (что еще лучше) используйте оператор using .

Если вы когда-нибудь столкнетесь с этим вопросом в будущем, просто узнайте, какие интерфейсы он реализует. Как только вы увидите IDisposable , вы поймете, что нужно утилизировать.

0
ответ дан 3 December 2019 в 00:38
поделиться

Если вам нужно очистить поток, используйте null; В противном случае используйте Dispose (); метод, если ваше приложение больше не требует использования потока.

0
ответ дан 3 December 2019 в 00:38
поделиться