Ввод/вывод
Консольный ввод. Преобразование значений
Следует иметь в виду, что чтение информации из входного потока класса Console связано с получением из буфера клавиатуры СИМВОЛЬНЫХ последовательностей и в большинстве случаев предполагает дальнейшие преобразования этих последовательностей к соответствующему типу значений.
Консольный ввод предполагает использование уже известных статических (!) функций – членов класса Console:
-
Read() – читает следующий знак из стандартного входного потока:
public static int Read();
Возвращаемое значение:
Следующий знак из входного потока или значение " –1 ", если знаков больше нет.
Метод не будет завершен до окончания операции чтения, например при нажатии клавиши "Ввод". При наличии данных входной поток содержит ввод пользователя и зависящую от окружения последовательность знаков перехода на новую строку.
-
ReadLine() – считывает следующую строку символов из стандартного входного потока:
public static string ReadLine();
Возвращаемое значение:
Следующая строка из входного потока или пустая ссылка, если знаков больше нет.
Строка определяется как последовательность символов, завершаемая парой escape-символов carriage return line feed (" \r\n ") – ( hexadecimal 0x000d ), ( hexadecimal 0x000a ). При этом возвращаемая строка эти символы не включает.
В любом случае речь идет о получении символьной информации. Символьная информация достаточно просто извлекается из входного потока. Однако это не самая большая составляющая общего объема обрабатываемой информации. Как правило, содержимое входного потока приходится приводить к одному из базовых типов.
В .NET FCL реализован процесс преобразования информации в рамках Общей Системы Типов (CTS).
.NET Framework Class Library включает класс System.Convert, в котором реализовано множество функций-членов, предназначенных для выполнения ЗАДАЧИ ПРЕОБРАЗОВАНИЯ ЗНАЧЕНИЙ ОДНОГО базового ТИПА В ЗНАЧЕНИЯ ДРУГОГО базового ТИПА. В частности, в этом классе содержится множество функций (по нескольку функций на каждый базовый тип), обеспечивающих попытку преобразования символьных строк в значения базовых типов.
Кроме того, множество классов, входящих в CTS и FCL, располагают вариантами функции Parse(), основное назначение которой – ПОПЫТКА преобразования строк символов (в частности, получаемых в результате выполнения методов консольного ввода) в значения соответствующих типов.
При обсуждении функций преобразования неслучайно употребляется слово "попытка". Не каждая строка символов может быть преобразована к определенному базовому типу. Для успешного преобразования предполагается, что символьная строка содержит символьное представление значения в некотором общепринятом формате в соответствии с соответствующей существующей в операционной системе настройкой языковых параметров, представления чисел, времени и дат. С аналогичной ситуацией мы уже сталкивались при обсуждении понятия литералов. В случае успешного преобразования функции возвращают результат преобразования в виде значения соответствующего типа.
Если же значение одного типа не может быть преобразовано к значению другого типа, преобразующая функция ВЫРАБАТЫВАЕТ ИСКЛЮЧЕНИЕ, с помощью которого CLR (то есть среда выполнения!) уведомляется о неудачной попытке преобразования.
Файловый ввод/вывод
описывает, каким образом операционная система должна открывать файл.
FileAccess enumerations:
Члены перечисления | Описание |
---|---|
Read | Доступ к файлу для чтения. Данные могут быть прочитаны из файла. Для обеспечения возможностей чтения/записи может комбинироваться со значением Write |
ReadWrite | Доступ к файлу для чтения/записи |
Write | Доступ к файлу для записи. Данные могут быть записаны в файл. Для обеспечения возможностей чтения/записи может комбинироваться со значением Read |
using System; using System.IO; namespace fstream00 { class Class1 { static string[] str = { "1234567890", "qwertyuiop", "asdfghjkl", "zxcvbnm", }; static void Main(string[] args) { int i; // Полное имя файла. string filename = @"D:\Users\WORK\Cs\fstream00\test.txt"; string xLine = ""; char[] buff = new char[128]; for (i = 0; i < 128; i++) buff[i] = (char)25; // Запись в файл. FileStream fstr = new FileStream(filename, FileMode.Create, FileAccess.Write); BufferedStream buffStream = new BufferedStream(fstr); StreamWriter streamWr = new StreamWriter(buffStream); for (i = 0; i < str.Length; i++) { streamWr.WriteLine(str[i]); } streamWr.Flush(); streamWr.Close(); Console.WriteLine("–––––––––––––––––––––––––––––––––––––––––––"); fstr = new FileStream(filename, FileMode.Open, FileAccess.Read); StreamReader streamRd = new StreamReader(fstr); for ( ; xLine != null; ) { xLine = streamRd.ReadLine(); Console.WriteLine(xLine); } Console.WriteLine("––––––––––––––––––––––––––––––––––––––––––––"); fstr.Seek(0, SeekOrigin.Begin); streamRd.Read(buff,0,10); Console.WriteLine(new string(buff)); Console.WriteLine("1––––––––––––––––––––––––––––––––––––––––––"); streamRd.Read(buff,0,20); Console.WriteLine(new string(buff)); Console.WriteLine("2––––––––––––––––––––––––––––––––––––––––––"); Console.WriteLine(streamRd.Read(buff,0,15)); i = (int)fstr.Seek(–20, SeekOrigin.Current); Console.WriteLine(streamRd.ReadLine()); Console.WriteLine("3––––––––––––––––––––––––––––––––––––––––––"); } } }Листинг 11.1.
Пример перенаправления потоков. В файл можно записать информацию, используя привычные классы и методы!
using System; using System.Collections.Generic; using System.Text; using System.IO; namespace OutFile { class Program { static void Main(string[] args) { string buff; FileStream outFstr, inFstr; // Ссылки на файловые потоки. // Ссылка на выходной поток. Свойства и методы, // которые обеспечивают запись в... StreamWriter swr; // Ссылка на входной поток. Свойства и методы, // которые обеспечивают чтение из... StreamReader sr; // Класс Console – средство управления ПРЕДОПРЕДЕЛЕННЫМ потоком. // Сохранили стандартный выходной поток, // связанный с окошком консольного приложения. TextWriter twrConsole = Console.Out; // Сохранили стандартный входной поток, связанный с буфером клавиатуры. TextReader trConsole = Console.In; inFstr = new FileStream (@"F:\Users\Work\readme.txt", FileMode.Open, FileAccess.Read); sr = new StreamReader(inFstr); // Входной поток, связанный с файлом. outFstr = new FileStream (@"F:\Users\Work\txt.txt", FileMode.Create, FileAccess.Write); swr = new StreamWriter(outFstr); // Выходной поток, связанный с файлом. // А вот мы перенастроили предопределенный входной поток. // Он теперь связан не с буфером клавиатуры, а с файлом, открытым для чтения. Console.SetIn(sr); Console.SetOut(swr); while (true) { // Но поинтересоваться в предопределенном потоке отностительно // конца файла невозможно. // Такого для предопределенных потоков просто не предусмотрено. if (sr.EndOfStream) break; // А вот читать - можно. buff = Console.ReadLine(); Console.WriteLine(buff); } Console.SetOut(twrConsole); Console.WriteLine("12345"); Console.SetOut(swr); Console.WriteLine("12345"); Console.SetOut(twrConsole); Console.WriteLine("67890"); Console.SetOut(swr); Console.WriteLine("67890"); sr.Close(); inFstr.Close(); swr.Close(); outFstr.Close(); } } }Листинг 11.2.