Ввод и вывод в файл c#. Файловый и потоковый ввод-вывод

файл ). Несмотря на то, что потоки связываются с различными физическими устройствами, характер поведения всех потоков одинаков. Поэтому классы и методы ввода-вывода можно применить ко многим типам устройств.

На самом низком уровне иерархии потоков ввода-вывода находятся потоки, оперирующие байтами. Это объясняется тем, что многие устройства при выполнении операций ввода-вывода ориентированы на байты. Однако для человека привычнее оперировать символами, поэтому разработаны символьные потоки, которые фактически представляют собой оболочки, выполняющие преобразование байтовых потоков в символьные и наоборот. Кроме этого, реализованы потоки для работы с int -, double -, short - значениями, которые также представляют оболочку для байтовых потоков, но работают не с самими значениями, а с их внутренним представлением в виде двоичных кодов.

Мы открываем файл, подключая его к потоку. Потоки символов позволяют писать и читать текстовые файлы. Эти классы автоматически преобразуют поток байтов в поток символов. Ниже представлены все типы режимов открытия файлов. Этот класс предлагает несколько конструкторов, которые наиболее часто используются. Мы уже можем записать данные в файл.

Следует подчеркнуть следующий фрагмент кода. Вышеприведенная строка кода позволяет вам считывать данные из файла до тех пор, пока не будет достигнут конец файла. Затем все эти данные будут отображаться соответствующим образом. Если наша программа запускается, на экране отображаются следующие результаты.

Центральную часть потоковой С#-системы занимает класс Stream пространства имен System.IO. Класс Stream представляет байтовый поток и является базовым для всех остальных потоковых классов. Из класса Stream выведены такие байтовые классы потоков как:

  1. FileStream - байтовый поток, разработанный для файлового ввода-вывода
  2. BufferedStream - заключает в оболочку байтовый поток и добавляет буферизацию, которая во многих случаях увеличивает производительность программы;
  3. MemoryStream - байтовый поток, который использует память для хранения данных.

Программист может вывести собственные потоковые классы. Однако для подавляющего большинства приложений достаточно встроенных потоков.

Мы также научились писать и читать данные в текстовый файл. Мы продолжим эту тему в течение недели. Проще говоря, это строка неопределенной длины. Действие потоков будет продемонстрировано на примере крана, посредством которого мы вливаем воду в стекло. Когда наша программа хочет отобразить что-то на экране, она должна «отправить» воду кран. Стекло имеет ограниченную емкость и сначала необходимо опорожнить, чтобы принимать дополнительные порции. Не беспокойтесь, если вы не поймете вышеупомянутую аналогию, все выйдет вовремя.

Существует три типа потоков. Вероятно, каждый тонкий читатель знает, как загружать и отображать данные на экране консоли. Я, вероятно, разочарую вас - покажут только имя! Нам нужно создать еще одну строковую переменную и записать в нее имя и использовать каскадную вставку в поток. Просто внесите некоторые изменения в эту программу.

Подробно мы рассмотрим класс FileStream , классы StreamWriter и StreamReader , представляющие собой оболочки для класса FileStream и позволяющие преобразовывать байтовые потоки в символьные, а также классы BinaryWriter и BinaryReader , представляющие собой оболочки для класса FileStream и позволяющие преобразовывать байтовые потоки в двоичные для работы с int -, double -, short - и т.д. значениями.

Эта функция позволяет извлекать текст с клавиатуры, содержащей пробелы. Это показано в следующем примере. Используя потоки, мы можем читать и записывать файлы. Программа записывает строку в файл. Благодаря ему мы можем работать над надписями, как в обычном потоке. Представьте себе ситуацию, когда нам нужно преобразовать целое число в надпись.

Однако решение, представленное ниже, намного легче читать. На самом низком уровне файл интерпретируется как поток байтов. На пользовательском уровне файл состоит из последовательности смешанных типов данных: символов, арифметических значений, объектов.

Байтовый поток

Чтобы создать байтовый поток, связанный с файлом, создается объект класса FileStream . При этом в классе определено несколько конструкторов. Чаще всего используется конструктор, который открывает поток для чтения и/или записи:

FileStream(string filename, FileMode mode)

  1. параметр filename определяет имя файла, с которым будет связан поток ввода-вывода данных; при этом filename определяет либо полный путь к файлу, либо имя файла, который находится в папке bin/debug вашего проекта.
  2. параметр mode определяет режим открытия файла, который может принимать одно из возможных значений, определенных перечислением FileMode :
    • FileMode.Append - предназначен для добавления данных в конец файла;
    • FileMode.Create - предназначен для создания нового файла, при этом если существует файл с таким же именем, то он будет предварительно удален;
    • FileMode. CreateNew - предназначен для создания нового файла, при этом файл с таким же именем не должен существовать;
    • FileMоde.Open - предназначен для открытия существующего файла;
    • FileMode.ОpenOrCreate - если файл существует, то открывает его, в противном случае создает новый
    • FileMode.Truncate - открывает существующий файл, но усекает его длину до нуля

Если попытка открыть файл оказалась неуспешной, то генерируется одно из исключений: FileNotFoundException - файл невозможно открыть по причине его отсутствия, IOException - файл невозможно открыть из-за ошибки ввода-вывода, ArgumentNullException - имя файла представляет собой null -значение, ArgumentException - некорректен параметр mode, SecurityException - пользователь не обладает правами доступа, DirectoryNotFoundException - некорректно задан каталог.

В библиотеке предопределен набор операций для чтения и записи предопределенных типов. Эти операции могут быть расширены программистом для пользовательских типов данных. Запись в выходной поток выполняется с помощью оператора. Это делается с помощью оператора вставки.

В отсутствие инструкций форматирования создается форматирование по умолчанию 10, с правильным выравниванием в поле вывода. Для достижения пользовательского форматирования, отличного от значения по умолчанию, вы можете установить биты индикатора с помощью следующих функций.

Другая версия конструктора позволяет ограничить доступ только чтением или только записью:

FileStream(string filename, FileMode mode, FileAccess how)

  1. параметры filename и mode имеют то же назначение, что и в предыдущей версии конструктора;
  2. параметр how, определяет способ доступа к файлу и может принимать одно из значений, определенных перечислением FileAccess :
  1. FileAccess.Read - только чтение;
  2. FileAccess.Write - только запись;
  3. FileAccess.ReadWrite - и чтение, и запись.

После установления связи байтового потока с физическим файлом внутренний указатель потока устанавливается на начальный байт файла.

Биты индикатора формата делятся на 3 группы. В группе может быть установлен только один индикатор. По умолчанию минимальная ширина области отображения равна 0; его можно автоматически продлить, чтобы отображать дату со всеми цифрами. Если количество символов даты меньше минимальной ширины области отображения, выровняйте ее вправо и заполните левое пустое пространство.

Количество десятичных знаков, в которых отображается реальное число, можно установить с помощью. Существуют следующие манипуляторы. Индикатор децимального преобразования. Показатель октябрьского конвертирования. Шестнадцатеричный индекс шестнадцатеричного преобразования.

Для чтения очередного байта из потока, связанного с физическим файлом, используется метод ReadByte() . После прочтения очередного байта внутренний указатель перемещается на следующий байт файла. Если достигнут конец файла, то метод ReadByte() возвращает значение -1 .

Для побайтовой записи данных в поток используется метод WriteByte() .

По завершении работы с файлом его необходимо закрыть. Для этого достаточно вызвать метод Close () . При закрытии файла освобождаются системные ресурсы, ранее выделенные для этого файла, что дает возможность использовать их для работы с другими файлами.

Прежде чем приступать к работе с любым файлом, вам необходимо указать имя файла и режим работы с ним. Имя переменной, указанное во время открытия, будет использоваться для операций с файлами. В первых котировках мы указываем имя файла в операционной системе по расширению имени файла. Вторая кавычка обозначает работу с файловым режимом. Когда файл открывается, создается режим переменной, в котором сохраняется режим файла. Это может быть полезно, когда данные для уже созданного файла пересылаются из другой функции, и нет данных о работе с параметрами файла.

Рассмотрим пример использования класса FileStream , для копирования одного файла в другой. Но вначале создадим текстовый файл text.txt в папке bin/debug текущего проекта. И внесем в него произвольную информацию, например:

12 456 Hello! 23,67 4: Message using System; using System.Text; using System.IO; //для работы с потоками namespace MyProgram { class Program { static void Main() { try { FileStream fileIn = new FileStream("text.txt", FileMode.Open, FileAccess.Read); FileStream fileOut = new FileStream("newText.txt", FileMode.Create, FileAccess.Write); int i; while ((i = fileIn.ReadByte())!=-1) { //запись очередного файла в поток, связанный с файлом fIleOut fileOut.WriteByte((byte)i); } fileIn.Close(); fileOut.Close(); } catch (Exception EX) { Console.WriteLine(EX.Message); } } } }

Задание . Подумайте, почему для переменной i указан тип int . Можно было бы указать тип byte ?

Символьный поток

Чтобы создать символьный поток нужно поместить объект класса Stream (например, FileStream ) "внутрь" объекта класса StreamWriter или объекта класса StreamReader . В этом случае байтовый поток будет автоматически преобразовываться в символьный.

Класс StreamWriter предназначен для организации выходного символьного потока. В нем определено несколько конструкторов. Один из них записывается следующим образом:

StreamWriter(Stream stream);

где параметр stream определяет имя уже открытого байтового потока.

Например, создать экземпляр класса StreamReader можно следующим образом:

StreamWriter fileOut=new StreamWriter(new FileStream("text.txt", FileMode.Create, FileAccess.Write));

Этот конструктор генерирует исключение типа ArgumentException , если поток stream не открыт для вывода, и исключение типа ArgumentNullException , если он (поток) имеет null-значение.

Другой вид конструктора позволяет открыть поток сразу через обращения к файлу:

StreamWriter(string name);

где параметр name определяет имя открываемого файла.

Например, обратиться к данному конструктору можно следующим образом:

StreamWriter fileOut=new StreamWriter("c:\temp\t.txt");

И еще один вариант конструктора StreamWriter :

StreamWriter(string name, bool appendFlag);

где параметр name определяет имя открываемого файла;

параметр appendFlag может принимать значение true - если нужно добавлять данные в конец файла, или false - если файл необходимо перезаписать.

Например:

StreamWriter fileOut=new StreamWriter("t.txt", true);

Теперь для записи данных в поток fileOut можно обратиться к методу WriteLine . Это можно сделать следующим образом:

fileOut.WriteLine("test");

В данном случае в конец файла t.txt будет дописано слово test .

Класс StreamReader предназначен для организации входного символьного потока. Один из его конструкторов выглядит следующим образом:

StreamReader(Stream stream);

где параметр stream определяет имя уже открытого байтового потока.

В C# символы реализуются кодировкой Unicode. Для того, чтобы можно было обрабатывать текстовые файлы, содержащие русские символы, созданные, например, в Блокноте, рекомендуется вызывать следующий вид конструктора StreamReader:

StreamReader fileIn=new StreamReader ("c:\temp\t.txt", Encoding.GetEncoding(1251));

Параметр Encoding.GetEncoding(1251) говорит о том, что будет выполняться преобразование из кода Windows-1251 (одна из модификаций кода ASCII, содержащая русские символы) в Unicode. Encoding.GetEncoding(1251) реализован в пространстве имен System.Text .

Теперь для чтения данных из потока fileIn можно воспользоваться методом ReadLine . При этом если будет достигнут конец файла, то метод ReadLine вернет значение null.

Рассмотрим пример, в котором данные из одного файла копируются в другой, но уже с использованием классов StreamWriter и StreamReader .

static void Main() { StreamReader fileIn = new StreamReader("text.txt", Encoding.GetEncoding(1251)); StreamWriter fileOut=new StreamWriter("newText.txt", false); string line; while ((line=fileIn.ReadLine())!=null) //пока поток не пуст { fileOut.WriteLine(line); } fileIn.Close(); fileOut.Close(); }

Задание . Выясните, для чего предназначен метод ReadToEnd() и когда имеется смысл его применять.

Таким образом, данный способ копирования одного файла в другой, даст нам тот же результат, что и при использовании байтовых потоков. Однако, его работа будет менее эффективной, т.к. будет тратиться дополнительное время на преобразование байтов в символы. Но у символьных потоков есть свои преимущества. Например, мы можем использовать регулярные выражения для поиска заданных фрагментов текста в файле.

static void Main() { StreamReader fileIn = new StreamReader("text.txt"); StreamWriter fileOut=new StreamWriter("newText.txt", false); string text=fileIn.ReadToEnd(); Regex r= new Regex(@"[-+]?\d+"); Match integer = r.Match(text); while (integer.Success) { fileOut.WriteLine(integer); integer = integer.NextMatch(); } fileIn.Close(); fileOut.Close(); }

Эта документация перемещена в архив и не поддерживается.

Файловый и потоковый ввод-вывод относятся к передаче данных с носителя информации или на него. В платформе.NET Framework пространства имен System.IO содержат типы, которые обеспечивают как синхронные, так и асинхронные операции чтения и записи для потоков и файлов данных. Кроме того, эти пространства имен содержат типы, выполняющие сжатие и распаковку файлов, а также типы, которые обеспечивают взаимодействие через каналы и последовательные порты.

Файл - это упорядоченная и именованная последовательность байтов, имеющая постоянное хранилище. При работе с файлами используются пути к каталогам, запоминающие устройства, а также имена файлов и каталогов. В отличие от файла, поток - это последовательность байтов, которую можно использовать для записи или чтения из вспомогательного запоминающего устройства, являющегося одним из устройств хранения информации (например, дисков или памяти). Есть несколько видов запоминающих устройств, отличных от дисков, и существует несколько видов потоков, помимо файловых потоков, например сетевые потоки, потоки памяти и потоки каналов.

  • Чтение и запись больших объемов данных может быть ресурсоемкой. Эти задачи необходимо выполнять асинхронно, если приложение должно продолжать отвечать на запросы пользователя. В случае синхронных операций ввода-вывода поток пользовательского интерфейса будет заблокирован до тех пор, пока ресурсоемкая операция не завершится. При разработке приложений для Магазин Windows 8.x используйте асинхронные операции ввода-вывода, чтобы не создавалось впечатления, что приложение прекратило свою работу.

    Имена асинхронных элементов содержат Async , например: , и . Используйте эти методы с ключевыми словами async и await .

    Дополнительные сведения см. в разделе .

    Сжатием называется процесс сокращения размера сохраняемого файла. Распаковка - это процесс извлечения содержимого сжатого файла, что приводит его в формат, пригодный для использования. Пространство имен содержит типы для сжатия и распаковки файлов и потоков.

    При сжатии и распаковке файлов и потоков часто используются следующие классы:

    • Изолированное хранилище - это механизм хранения данных, обеспечивающий изоляцию и безопасность путем определения стандартизованных способов сопоставления кода с хранимыми данными. Хранилище предоставляет виртуальную файловую систему, изолированную по пользователю, сборке и (необязательно) домену. Изолированное хранилище особенно полезно в том случае, когда приложение не имеет разрешения на доступ к файлам пользователя. Можно сохранить параметры или файлы для приложения таким способом, который контролируется политикой безопасности компьютера.

      Изолированное хранилище недоступно для приложений Магазин Windows 8.x. Вместо этого используйте классы данных приложения, которые содержатся в пространстве имен . Подробнее см. в разделе Доступ к данным приложения в Центре разработки для Windows.

      Часто используются следующие классы, реализующие изолированное хранилище:

        NET для приложений Магазина Windows 8.x содержат множество типов для чтения и записи в потоки, однако этот набор содержит не все типы ввода-вывода платформы.NET Framework.

        Следует отметить некоторые важные различия в использовании операций ввода-вывода для приложений в стиле Магазин Windows 8.x:

        • Специальные типы, относящиеся к операциям с файлами, такие как , и , не включены в.NET для приложений Магазина Windows 8.x. Вместо этого используйте типы в пространстве имен Среда выполнения Windows, такие как и .

          Изолированное хранилище недоступно. Вместо этого используйте данные приложения .

        • Используйте асинхронные методы, такие как и , чтобы предотвратить блокировку потока пользовательского интерфейса.

          При использовании классов в пространстве имен необходимо выполнить требования безопасности операционной системы, такие как списки управления доступом для контроля доступа к файлам и каталогам. Это требование дополняет остальные требования . Списками управления доступом можно управлять программно. Дополнительные сведения см. в разделе .

          По умолчанию политика безопасности не позволяет обращаться к файлам на компьютере пользователя через Интернет или из приложений интрасети. Поэтому при составлении кода не используйте классы ввода-вывода, которым нужен путь к физическому файлу, загружаемому через Интернет или интрасеть. Вместо этого используйте для обычных приложений.NET Framework или данные приложения для приложений Магазин Windows 8.x.

          Проверка безопасности выполняется только при создании потока. Поэтому не рекомендуется открывать поток, а затем передавать его коду с меньшим уровнем доверия или доменам приложений.

          Заголовок Описание
          Содержит список задач ввода-вывода, связанных с файлами, каталогами и потоками, а также ссылки на соответствующее содержимое и примеры для каждой задачи.
          Описывает преимущества и основные операции асинхронного ввода и вывода.
          Описывает механизм хранения данных, обеспечивающий автономность и безопасность путем определения стандартизованных способов сопоставления кода с защищенными данными.
          Описывает операции с анонимными и именованными каналами в.NET Framework.
          Описание отображаемых в память файлов, позволяющих разместить содержимое файлов с диска в виртуальной памяти. С их помощью можно вносить изменения в очень большие файлы и создавать совместно используемую память для межпроцессного взаимодействия.

          Показ:



  • Есть вопросы?

    Сообщить об опечатке

    Текст, который будет отправлен нашим редакторам: