c# отличие StreamReader от FileStream
Не могу понять, почему при
private static GoogleCredential? _credential;
private static readonly string[] _scopes = {SheetsService.Scope.Spreadsheets};
private static GoogleCredential GetCredential()
{
var stream = new StreamReader(File.OpenRead("client_secrets.json"));
_credential = GoogleCredential.FromStream(stream.ReadToEnd()).CreateScoped(_scopes);
return _credential;
}
получаю ошибку
Error CS1503 Argument 1: cannot convert from 'string' to 'System.IO.Stream'
Хотя, при использовании аналогичного FileStream такой ошибки нет:
var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
_credential = GoogleCredential.FromStream(stream).CreateScoped(_scopes);
Также код работает, если не создавать поток, а просто указать метод FromFile и указать json файл напрямую (я так понимаю, в таком случае поток создается внутри метода?):
_credential = GoogleCredential.FromFile("client_secrets.json").CreateScoped(_scopes);
Ответы (1 шт):
StreamReader - это обертка над Stream, базовый класс для StreamReader является TextReader и предназначен он для чтения потока как текстовых данных, название говорит само за себя.
Stream же предназначен для работы с двоичными потоками данных, в этом и разница. Чтобы обратиться к двоичному потоку внутри StreamReader, нужно использовать свойство TextReader.BaseStream, для вашего случая stream.BaseStream.
Напротив FileStream это как раз наследник от того самого Stream. Другими словами, это разные классы, и задачи решают они разные, не стоит их путать.
Не стоит так же забывать про IDisposable, в этом случае код будет выглядеть как-то так.
private static GoogleCredential GetCredential()
{
using Stream stream = new File.OpenRead("client_secrets.json");
return GoogleCredential.FromStream(stream).CreateScoped(_scopes);
}
А GoogleCredential.FromFile("client_secrets.json") действительно сам создает поток внутри себя.
Так что такой вариант эквивалентен по поведению, но более лаконичен:
private static GoogleCredential GetCredential()
{
return GoogleCredential.FromFile("client_secrets.json").CreateScoped(_scopes);
}
.FromStream больше полезен, когда данные не в файле, а где-то в другом месте, либо на момент написания кода неизвестно, где именно:
private static GoogleCredential GetCredential(Stream stream)
{
return GoogleCredential.FromStream(stream).CreateScoped(_scopes);
}
Работа по созданию потока здесь за пределами метода. А потом может быть создан не обязательно из файла.