Программирование PC C#: файловый ввод/вывод Fri, April 19 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

C#: файловый ввод/вывод Печать
Добавил(а) microsin   

Файл (file) это коллекция данных, сохраненных на диске с определенным именем и по определенному пути на этом диске. Когда файл открывается для чтения или записи, он становится потоком (stream).

Поток в сущности это последовательность байт, проходящих через канал обмена данными. Есть 2 основных потока: поток ввода (input stream) и поток вывода (output stream). Поток ввода используется для чтения данных из файла (read operation) и поток вывода используется для записи данных в файл (write operation).

[Классы ввода/вывода C#]

Пространство имен (namespace) System.IO содержит различные классы, используемые для выполнения нескольких операций с файлами, таких как создание и удаление файлов, чтение из них и запись в них, закрытие файла, навигация по системе каталогов файловой системы, доступ к информации о файле (время создания, атрибуты) и т. д.

В следующей таблице показаны некоторые обычно чаще всего используемые не абстрактные классы из System.IO namespace:

Имя класса Описание
BinaryReader Читает примитивные данные из двоичного потока.
BinaryWriter Записывает примитивные данные в двоичном формате.
BufferedStream Временное хранилище байтового потока данных.
Directory Помогает работать со структурой каталогов файловой системы.
DirectoryInfo Используется для выполнения операций над каталогами.
DriveInfo Предоставляет информацию о приводах (дисках).
File Помогает в манипуляциях с файлами.
FileInfo Используется для выполнения операций с файлами.
FileStream Используется для чтения и записи любого места в файле.
MemoryStream Используется для произвольного доступа к данным потока, сохраненного в памяти.
Path Операции над информацией пути файлов и каталогов.
StreamReader Используется для чтения символов в байтовом потоке.
StreamWriter Используется для записи символов в поток.
StringReader Используется для чтения из буфера строки.
StringWriter Используется для записи в буфер строки.

Класс FileStream. Этот класс из System.IO namespace помогает в чтении, записи и закрытие файлов после их использования. Этот класс происходит от абстрактного класса Stream.

Чтобы создать новый файл или открыть существующий файл, Вам нужно создать объект FileStream. Синтаксис создания объекта FileStream следующий:

FileStream < object_name> = new FileStream( < имя файла>,
                                            < FileMode Enumerator>,
                                            < FileAccess Enumerator>,
                                            < FileShare Enumerator>);

Например, вот так мы создаем объект FileStream F для чтения файла sample.txt:

FileStream F = new FileStream("sample.txt",
                              FileMode.Open,
                              FileAccess.Read,
                              FileShare.Read);

Назначение параметров конструктора класса FileStream:

Параметр Описание
FileMode Перечисление FileMode определяет различные методы, которые применяются для работы с файлами:

Append - открывает существующий файл и перемещает позицию ввода (так называемый курсор файла) в конец файла, или создает новый файл, если указанный по имени файл не существует.
Create - создает новый файл.
CreateNew - указывает операционной системе, что она должна создать новый файл.
Open - открывает существующий файл.
OpenOrCreate - указывает операционной системе, что нужно открыть файл, если он существует, и если он не существует, то нужно создать новый файл.
Truncate - откроет существующий файл и обрежет его, в результате файл станет пустым (его размер составит 0 байт).
FileAccess Перечислитель, определяющий доступ к файлу: Read (только чтение), ReadWrite (чтение и запись) и Write (только запись).
FileShare Перечисление, определяющее совместное использование файла:

Inheritable - позволяет наследовать доступ к дескриптору файла для дочерних процессов.
None - запрещает совместный доступ к текущему файлу.
Read - позволяет другим потокам открыть файл на чтение.
ReadWrite - позволяет совместную работу с файлом на чтение и запись.
Write - позволяет другим потокам открыть файл на запись.

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

using System;
using System.IO;
 
namespace FileIOApplication
{
   class Program
   {
      static void Main(string[] args)
      {
         FileStream F = new FileStream("test.dat", FileMode.OpenOrCreate, 
            FileAccess.ReadWrite);
         
         for (int i = 1; i < 21; i++)
            F.WriteByte((byte)i);
         F.Position = 0;
         for (int i = 0; i < 21; i++)
            Console.Write(F.ReadByte() + " ");
         F.Close();
         Console.ReadKey();
      }
   }
}

Когда этот код будет скомпилирован и запущен на выполнение, то мы получим следующий результат:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 -1

[Более сложные операции с файлами на C#]

В предыдущем примере был показан простейший пример операций с файлом на C#. Однако для использование классов System.IO в полную силу следует знать их часто используемые свойства и методы.

Классы StreamReader и StreamWriter помогают в доступе к информации текстового файла на чтение и запись [2]. Они наследуются из абстрактного базового класса Stream, который поддерживает чтение и запись байт файлового потока.

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

Метод Описание
public override void Close() Закрывает объект StreamReader и нижележащий поток, и освобождает любые ресурсы системы, связанные с этим читающим объектом.
public override int Peek() Вернет следующий доступный символ без перемещения позиции чтения в файле.
public override int Read() Читает следующий символ из входного потока с переходом к следующему символу.

Следующий пример показывает чтение файла mytext.txt, находящегося в каталоге TEMP диска C:.

using System;
using System.IO;
 
namespace FileApplication
{
   class Program
   {
      static void Main(string[] args)
      {
         try
         {
            // Создание экземпляра класса StreamReader для чтения из файла.
            // Оператор using обрамляет код, где используется StreamReader.
            using (StreamReader sr = new StreamReader("c:/temp/mytext.txt"))
            {
               string line;
               // Построчное чтение файла и отображение этих строк,
               // пока не будет достигнут конец файла.
               while ((line = sr.ReadLine()) != null)
                  Console.WriteLine(line);
            }
         }
         catch (Exception e)
         {
            // Обработка исключения даст пользователю информацию,
            // что пошло не так.
            Console.WriteLine("The file could not be read:");
            Console.WriteLine(e.Message);
         }
         Console.ReadKey();
      }
   }
}

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

StreamWriter. Класс StreamWriter наследуется из абстрактного класса TextWriter, который предоставляет способ записи последовательности символов. Следующая таблица описывает наиболее часто используемые методы этого класса:

Метод Описание
public override void Close() Закрывает текущий объект StreamWriter и связанный с ним нижележащий поток.
public override void Flush() Очищает все буферы текущего записывающего объекта, что приводит к тому, что все хранящиеся в буфере (кэше) данные записываются в нижележащий поток.
public virtual void Write(bool value) Записывает текст, представляющий двоичное значение в строку текста или в поток (унаследовано от TextWriter).
public override void Write(char value) Записывает символ в поток.
public virtual void Write(decimal value) Записывает текстовое представление десятичного значения в строку текста или поток.
public virtual void Write(double value) Записывает текстовое представление 8-байтного значения в формате с плавающей точкой в строку текста или поток.
public virtual void Write(int value) Записывает текстовое представление 4-байтного значения целого числа со знаком в строку текста или поток.
public override void Write(string value) Записывает строку в поток.
public virtual void WriteLine() Записывает терминатор строки в строку текста или поток.

Для получения полного списка методов обратитесь к документации C# от Microsoft.

Следующий пример демонстрирует запись файла names.txt в текущий каталог.

using System;
using System.IO;
 
namespace FileApplication
{
   class Program
   {
      static void Main(string[] args)
      {
         string[] names = new string[] {"Иван Петров", "Козьма Прутков"};
         
         // Запись файла:
         using (StreamWriter sw = new StreamWriter("names.txt"))
         {
            foreach (string s in names)
               sw.WriteLine(s);
         }
         
         // Чтение и отображение каждой строки из файла.
         string line = "";
         using (StreamReader sr = new StreamReader("names.txt"))
         {
            while ((line = sr.ReadLine()) != null)
               Console.WriteLine(line);
         }
         Console.ReadKey();
      }
   }
}

Когда этот код будет скомпилирован и выполнен, то он покажет в консоли следующий результат:

Иван Петров
Козьма Прутков

Классы BinaryReader и BinaryWriter помогают реализовать чтение и запись двоичных файлов [3].

BinaryReader. Класс BinaryReader используется для чтения двоичных данных из файла. Объект BinaryReader создается передачей в его конструктор объекта FileStream.

Следующая таблица описывает часто используемые методы класса BinaryReader.

Метод Описание
public override void Close() Закрывает объект BinaryReader и нижележащий поток.
public virtual int Read() Читает символы из нижележащего потока с переходом в следующую позицию чтения в потоке.
public virtual bool ReadBoolean() Читает двоичное значение из текущего потока с переводом позиции чтения в следующую позицию в потоке на 1 байт.
public virtual byte ReadByte() Читает следующий байт из текущего потока и переводит текущую позицию в потоке на 1 байт.
public virtual byte[] ReadBytes(int count) Читает указанное количество байт из текущего потока в массив байт и переводит текущую позицию в потоке вперед на это количество байт.
public virtual char ReadChar() Читает следующий символ из текущего потока и перемещает позицию чтения в нем на следующий символ в соответствии с используемой кодировкой (Encoding) и прочитанным символом.
public virtual char[] ReadChars(int count) Читает указанное количество символов из текущего потока, возвращает эти данные в массиве символов, и перемещает позицию чтения в потоке вперед в соответствии с кодировкой (Encoding) и специфическими символами, прочитанными из потока.
public virtual double ReadDouble() Читает 8-байтное значение с плавающей точкой и перемещает позицию чтения в потоке вперед на 8 байт.
public virtual int ReadInt32() Читает 4-байтное целочисленное значение со знаком и перемещает позицию чтения в потоке вперед на 4 байта.
public virtual string ReadString() Читает строку из текущего потока. Строка снабжена префиксом длины, закодированное как целое число блоками по 7 бит.

BinaryWriter. Класс BinaryWriter используется для записи двоичных данных в файл. Объект BinaryWriter создается путем передачи в его конструктор объекта FileStream.

Следующая таблица описывает часто используемые методы класса BinaryWriter.

Метод Описание
public override void Close() Закрывает объект BinaryWriter и нижележащий поток.
public virtual void Flush() Очищает все буферы текущего записывающего объекта, в результате всего все буферизированные (кэшированные) данные передаются в нижележащее устройство (говоря по-русски, сбрасываются на диск).
public virtual long Seek(int offset, SeekOrigin origin) Устанавливает позицию в текущем потоке.
public virtual void Write(bool value) Записывает 1 байт двоичного значения в текущий поток, где 0 обозначает false и 1 обозначает true.
public virtual void Write(byte value) Записывает байт (беззнаковое 8-битное целое число) в текущий поток и перемещает текущую позицию в потоке вперед на 1 байт.
public virtual void Write(byte[] buffer) Записывает массив байт в нижележащий поток.
public virtual void Write(char ch) Записывает символ Unicode в текущий поток, и перемещает текущую позицию в потоке вперед на количество байт в соответствии с текущей кодировкой (Encoding) и записанным символом.
public virtual void Write(char[] chars) Записывает массив символов в текущий поток и перемещает текущую позицию потока вперед в соответствии с используемой кодировкой (Encoding) и спецификой символов, записанных в поток.
public virtual void Write(double value) Записывает 8-байтное значение с плавающей точкой в текущий поток и перемещает позицию потока вперед на 8 байт.
public virtual void Write(int value) Записывает 4-байтное целое число со знаком в текущий поток и перемещает позицю потока вперед на 4 байта.
public virtual void Write(string value) Записывает строку, снабженную префиксом длины, в поток в текущей кодировке BinaryWriter, и перемещает текущую позицию потока вперед в соответствии с кодировкой и спецификой символов записанной строки.

Для получения полного списка методов обратитесь к документации C# от Microsoft.

Следующий пример демонстрирует чтение и запись двоичного файла:

using System;
using System.IO;
 
namespace BinaryFileApplication
{
   class Program
   {
      static void Main(string[] args)
      {
         BinaryWriter bw;
         BinaryReader br;
         
         int i = 25;
         double d = 3.14157;
         bool b = true;
         string s = "Я рад";
         
         //Создание файла.
         try
         {
            bw = new BinaryWriter(new FileStream("mydata", FileMode.Create));
         }
         catch (IOException e)
         {
            Console.WriteLine(e.Message + "\n Нельзя создать файл.");
            return;
         }
         
         //Запись файла.
         try
         {
            bw.Write(i);
            bw.Write(d);
            bw.Write(b);
            bw.Write(s);
         }
         catch (IOException e)
         {
            Console.WriteLine(e.Message + "\n Нельзя записать в файл.");
            return;
         }
         bw.Close();
         
         //Чтение файла.
         try
         {
            br = new BinaryReader(new FileStream("mydata", FileMode.Open));
         }
         catch (IOException e)
         {
            Console.WriteLine(e.Message + "\n Нельзя открыть файл.");
            return;
         }
         
         try
         {
            i = br.ReadInt32();
            Console.WriteLine("Integer data: {0}", i);
            d = br.ReadDouble();
            Console.WriteLine("Double data: {0}", d);
            b = br.ReadBoolean();
            Console.WriteLine("Boolean data: {0}", b);
            s = br.ReadString();
            Console.WriteLine("String data: {0}", s);
         }
         catch (IOException e)
         {
            Console.WriteLine(e.Message + "\n Нельзя прочитать из файла.");
            return;
         }
         br.Close();
         Console.ReadKey();
      }
   }
}

Когда этот код скомпилирован и запущен на выполнение, то он выведет следующий результат:

Integer data: 25
Double data: 3.14157
Boolean data: True
String data: Я рад

C# позволяет Вам работать с директориями и файлами, используя набор специальных классов, таких как DirectoryInfo и FileInfo [4].

DirectoryInfo. Класс DirectoryInfo происходит из класса FileSystemInfo. В нем содержатся различные методы для создания, переименования/перемещения, просмотра содержимого директорий и их подкаталогов. Этот класс не может быть унаследован.

В таблице приведены используемые обычно свойства класса DirectoryInfo:

Свойство Описание
Attributes Возвращает значения атрибутов текущего файла или директории.
CreationTime Возвращает время создания текущего файла или директории.
Exists Возвращает двоичное значение, показывающее, существует ли директория.
Extension Возвращает строку, представляющую расширение файла.
FullName Возвращает полный путь до директории или файла.
LastAccessTime Возвращает время последнего доступа к текущему файлу или директории.
Name Возвращает имя этого экземпляра DirectoryInfo.

Часто используемые методы класса DirectoryInfo:

Метод Описание
public void Create() Создает директорию.
public DirectoryInfo CreateSubdirectory(string path) Создает подкаталог или подкаталоги по указанному пути. Для этого экземпляра класса DirectoryInfo указанный путь может быть относительный.
public override void Delete() Удаляет директорию этого DirectoryInfo, если она пустая.
public DirectoryInfo[] GetDirectories() Возвратит подкаталоги текущей директории.
public FileInfo[] GetFiles() Возвратит список файлов из текущей директории.

Для получения полного списка свойств и методов обратитесь к документации C# от Microsoft.

FileInfo. Класс FileInfo также происходит от класса FileSystemInfo. Его свойства и методы его экземпляра позволяют создавать, копировать, удалять, переименовывать файлы, а также помогают открывать файлы и создавать объекты FileStream. Этот класс не может быть унаследован.

В таблице приведены используемые обычно свойства класса FileInfo:

Свойство Описание
Attributes Возвратит атрибуты для текущего файла.
CreationTime Возвратит время создания текущего файла.
Directory Возвратит экземпляр директории, которой принадлежит файл.
Exists Возвратит двоичное значение, показывающее, существует файл или нет.
Extension Возвратит строку, представляющую расширение файла.
FullName Возвратит полный путь до файла.
LastAccessTime Возвратит время последнего доступа к текущему файлу.
LastWriteTime Возвратит время последней активности записи файла.
Length Возвратит размер в байтах текущего файла.
Name Возвратит имя файла.

Часто используемые методы класса FileInfo:

Метод Описание
public StreamWriter AppendText() Создает StreamWriter, который добавляет текст к файлу, представленному этим экземпляром FileInfo.
public FileStream Create() Создает файл.
public override void Delete() Полностью удаляет файл с диска.
public void MoveTo(string destFileName) Переименовывает (перемещает в новое место) указанный файл с предоставлением опции указания нового имени файла.
public FileStream Open(FileMode mode) Откроет файл в указанном режиме.
public FileStream Open(FileMode mode, FileAccess access) Откроет файл в указанном режиме с доступом только чтение, только запись или и чтение, и запись.
public FileStream Open(FileMode mode, FileAccess access, FileShare share) Откроет файл в указанном режиме с доступом только чтение, только запись или и чтение, и запись, и с указанной опцией совместного доступа.
public FileStream OpenRead() Создает FileStream только для чтения.
public FileStream OpenWrite() Создает FileStream только для записи.

Для получения полного списка свойств и методов обратитесь к документации C# от Microsoft.

Следующий пример демонстрирует использование вышеупомянутых классов:

using System;
using System.IO;
 
namespace WindowsFileApplication
{
   class Program
   {
      static void Main(string[] args)
      {
         //Создание объекта DirectoryInfo:
         DirectoryInfo mydir = new DirectoryInfo(@"c:\Windows");
         
         //Получение списка файлов в этой директории, их имена и размеры:
         FileInfo [] f = mydir.GetFiles();
         foreach (FileInfo file in f)
            Console.WriteLine("File Name: {0} Size: {1}", file.Name, file.Length);
         Console.ReadKey();
      }
   }
}

После этого скомпилируйте и запустите эту программу, это отобразит имена файлов и их соответствующие размеры в директории Windows.

[Ссылки]

1. C# - File I/O site:tutorialspoint.com.
2. Reading from and Writing into Text files site:tutorialspoint.com.
3. Reading from and Writing into Binary files site:tutorialspoint.com.
4. Manipulating the Windows file system site:tutorialspoint.com.

 

Добавить комментарий


Защитный код
Обновить

Top of Page