Лабораторная работа №6. Файлы.
Требуемые условия завершения
Открыто с: четверг, 21 марта 2019, 11:55
Срок сдачи: четверг, 21 марта 2019, 13:30
Класс FileStream
Класс FileStream представляет возможности по считыванию из файла и записи в файл. Он позволяет работать как с текстовыми файлами, так и с бинарными. Он создаётся следующим образом:FileStream fileStream = new FileStream(path, FileMode.Create);Здесь в конструктор передается два параметра: путь к файлу и перечисление FileMode. Данное перечисление указывает на режим доступа к файлу и может принимать следующие значения:
- Append: если файл существует, то текст добавляется в конец файл. Если файла нет, то он создается. Файл открывается только для записи.
- Create: создается новый файл. Если такой файл уже существует, то он перезаписывается
- CreateNew: создается новый файл. Если такой файл уже существует, то он приложение выбрасывает ошибку
- Open: открывает файл. Если файл не существует, выбрасывается исключение
- OpenOrCreate: если файл существует, он открывается, если нет - создается новый
- Truncate: если файл существует, то он перезаписывается. Файл открывается только для записи.
Также можно использовать статические методы класса File, например
FileStream fileStream = File.Create(path); // создать новый файлили
FileStream fileStream = File.Open(path); // открыть файл с доступом на чтение и запись
Для работы с бинарными файлами предназначена пара классов BinaryWriter и BinaryReader. Эти классы позволяют читать и записывать данные в двоичном формате.
Основные метода класса BinaryWriter
- Close(): закрывает поток и освобождает ресурсы
- Flush(): очищает буфер, дописывая из него оставшиеся данные в файл
- Seek(): устанавливает позицию в потоке
- Write(): записывает данные в поток
Объект BinaryWriter создаётся так:
BinaryWriter binaryWriter = new BinaryWriter(fileStream);Для того, чтобы закрыть потоки и освободить ресурсы можно использовать метод Close(). Но удобнее использовать директиву using
using (FileStream fileStream = new FileStream(path, FileMode.Create)) using (BinaryWriter binaryWriter = new BinaryWriter(fileStream)) { // запись информации в файл }или можно сократить запись:
using (var binaryWriter = new BinaryWriter(File.Create(path))) { // запись информации в файл }
Бинарные файлы (запись)
- Создайте метод
static void CreateTheNewFile(string path, params int[] values)
который записывает в файл целых чисел набор значений, перечисленных через запятую.
Указание Есть разные виды ошибок, при котором работа с файлом невозможна, например отсутствие прав доступа к файлу. Чтобы программа не "вылетала", используйте конструкцию try...catchtry { // код, вызывающий ошибку } catch (IOException e) { Console.WriteLine($"Ошибка обработки файла {e.Message}"); }
Используйте try... catch в методе или поместите в блок try вызов метода.
Чтение элементов из файла (последовательный доступ)
Для чтения значений из файла используем объект типаBinaryReader
и его методы ReadBoolean()
, ReadChar()
, ReadDouble()
, ReadInt32()
и т.д. Создание объекта BinaryReader аналогично созданию объекта класса BinaryWriter
. Для последовательного чтения элементов из файла используем цикл:
using (FileStream fileStream = File.OpenRead(path)) using (BinaryReader binaryReader = new BinaryReader(fileStream)) { while (binaryReader.PeekChar()!=-1) { // обработка значений } }
- Создайте метод
static void ReadFile(string path, uint n = 10, string delimiter = ", ")
который принимает имя файла целых чисел и выводит их на консоль по N чисел в каждой строке (значение по умолчанию для N = 10, N > 0). Для пустого файла выводить сообщение <empty file>. (Используем свойство Length объекта FileStream)
Чтение элементов из файла (произвольный доступ)
В четырёх следующих задачах используем Метод long Seek(long offset, SeekOrigin origin)
устанавливает позицию в потоке со смещением на количество байт, указанных в параметре offset. SeekOrigin - перечисление с тремя значениями
- SeekOrigin.Begin: начало файла
- SeekOrigin.End: конец файла
- SeekOrigin.Current: текущая позиция в файле
Смещение может отрицательным, тогда курсор сдвигается назад, если положительное - то вперед. Если мы хотим прочитать из файла целых чисел третье число, мы пишем:
using (FileStream fileStream = File.OpenRead(path)) using (BinaryReader binaryReader = new BinaryReader(fileStream)) { fileStream.Seek(3 * sizeof(int), SeekOrigin.Begin); Console.Write(binaryReader.ReadInt32()); }
- Дан бинарный файл целых чисел. Обнулить его минимальный элемент (считать, что в файле он единственный). Если файл пуст, ничего не делать.
Указание. Во-первых, следует найти позицию минимального элемента (пользуясьPosition
).
Во вторых, с помощью методаSeek
, следует перейти в позицию минимального элемента и записать в файл переменную с нулевым значением.
Тестирование. В основной программе явно создайте и обработайте четыре файла (обязательно проверить пустой и файл из одного элемента). Для каждого файла: распечатать исходное содержимое, обнулить минимальный элемент, распечатать содержимое файла после изменения.
Указание к тестированию. Удобно записать имена созданных файлов в массив строк и обработать их в цикле. - Дан бинарный файл целых чисел. Увеличить все его элементы в два раза.
Тестирование. В основной программе явно создайте и обработайте четыре файла (обязательно проверить пустой и файл из одного элемента). - Дан файл целых чисел (возможно пустой). Инвертировать его (то есть изменить в нём порядок элементов на обратный).
Замечание. Не забудьте, что использовать вспомогательный файл запрещается.
Тестирование. В основной программе создать и обработать четыре файла (обязательно проверить пустой, файл из одного и двух элементов). - Дан бинарный файл. Удвоить его размер, записав в конец файла все его исходные элементы в обратном порядке.
Замечание. Не забудьте, что использовать вспомогательный файл запрещается.
Тестирование. В основной программе явно создайте и обработайте три файла (обязательно пустой файл, файл из одного целого числа).
Обработка текстовых файлов
// Цикл по строкам файла - первый способ using (var sr = new StreamReader("a.txt")) { string line; while ((line = sr.ReadLine()) != null) Console.WriteLine(line); } //Цикл по строкам файла - второй способ using (var sr = new StreamReader("a.txt")) { while (!sr.EndOfStream) Console.WriteLine(sr.ReadLine()); }
- Дан текстовый файл. Вывести все символы, содержащиеся в этом файле, и их коды (используйте метод
Read()
) . Посчитать общее количество символов в выходную переменную метода. Выяснить, какие коды у символов, обозначающих конец строки (ответ укажите в виде комментария). Выяснить код пробела. - Дано целое неотрицательное число N и символ C. Создать текстовый файл, содержащий N строк, первая из которых состоит из одного символа C, вторая — из двух, третья — из трёх и т.д. (Пользуемся методами Write() и WriteLine())
- Даны два текстовых файла. Дописать содержимое второго файла в конец первого. (Используем StreamWriter, найцдите подходящий конструктор)
- Дан текстовый файл. Удалить из него все пустые строки.
Указание. Все задачи на изменение содержимого текстового файла (кроме дополнения) решаются с использованием временного файла. Создание временного файла обсуждается на данной странице. Вам необходимо написать вспомогательную функциюMakeTempFileName
для генерации имени временного файла. Переделайте функцию с данной страницы на язык C# и инициализируйтеnewFileName
по описанному на странице принципу.
Средства System.IO.File для работы с текстовыми файлами
- Дан текстовый файл. Определить количество пустых строк в этом файле, используя статический метод
ReadLines
классаSystem.IO.File
. - Дан csv-файл, содержащий целые числа. Найти сумму чисел в каждой строке файла (решение оформить в виде функции, возвращающей массив целых чисел). Для пустой строки следует возвращать ноль.
Замечание 1. Каждая строка файла в формате CSV (comma-separated values — значения, разделённые запятыми) содержит значения, разделённые запятыми.
Указание 1. Использовать методSplit
для извлечения чисел из строк и методint.Parse
для преобразования их к типуinteger
для суммирования.
Замечание 2. Задачу можно решать с использованием явных циклов, либо с использованием методов последовательностей.
- Данная задача не требует чтения содержимого файлов.
- Создать в текущем каталоге папку
text_files
, создать там несколько текстовых файлов просто «руками», можете скопировать туда имеющиеся файлы). - Вывести имена файлов каталога
text_files
(процедура с одним параметром — именем каталога). - Переименовать все текстовые файлы каталога
text_files
, добавив к именам префиксhelp-
. Это следует выполнить в процедуру с двумя параметрами — именем каталога и префиксом). - Снова вывести имена файлов каталога.
Указания.
-
Чтобы получить список имён файлов каталога, используйте статический метод
System.IO.Directory.GetFiles
. Текущему каталогу соответствует имя'.'
, родительскому —'..'
. - Чтобы отделить собственно имя файла от всего пути к файлу (абсолютного или относительного) используйте статический метод
System.IO.Path.GetFileName
. - Для формирования имени файла с путём по пути и имени используйте
System.IO.Path.Combine
. Чтобы переименовать файл, используйте статический метод
System.IO.File.Move
.
- Создать в текущем каталоге папку
- Дано натуральное число K и текстовый файл, содержащий слова. Создать текстовый файл и записать в него все слова длины K из исходного файла по одному слову в строке.
Указание. Воспользуйтесь методомSystem.IO.File.ReadAllText
для чтения исходного файла иSystem.IO.File.WriteAllLines
для записи нового файла.
Замечание. Словом считать набор символов, не содержащий пробелов, знаков препинания и ограниченный пробелами, знаками препинания или началом/концом строки. Если исходный файл не содержит слов длины K, то оставить результирующий файл пустым.
Тестирование. Создать каталогinput-files/task-04
и добавить туда несколько входных текстовых файлов, на которых вы проводите тестирование. Убедиться, что соответствующие результирующие файлы содержат то, что нужно. - Дан текстовый файл, в каждой строке которого записано одно или несколько слов. Создать новый текстовый файл из одной строки, в которой через пробел записаны первые слова строк исходного файла, заканчивающиеся на заданную подстроку.