Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
шпора техпро.docx
Скачиваний:
7
Добавлен:
25.09.2019
Размер:
105.86 Кб
Скачать

Двоичные файлы

Общие сведения

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

При работе с файлами выполняются операции ввода - вывода. Операция ввода означает перепись данных с внешнего устройства (из входного файла) в основную память ЭВМ, операция вывода - это пересылка данных из основной памяти на внешнее устройство (в выходной файл). Файлы на внешних устройствах часто называют физическими файлами. Их имена определяются операционной системой. В программах имена файлов задаются с помощью строк. Например, имя файла на диске может иметь вид: c:\temp\myfile.dat .

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

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

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

  • установочные и завершающие операции

  • операции ввода-вывода

  • специальные операции

Для подключения возможностей по работе с файлами необходимо добавить пространство имён System.IO в программу.

using System.IO;

Установочные и завершающие операции

Используя классы BinaryWriter и BinaryReader можно создать свои файловые объекты для выполнения различных файловых операций

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

BinaryWriter outBin = new BinaryWriter

(File.Open("c:\\temp\\a1.dat", FileMode.Create ));

//outBin - созданный нами объект

//открытие существующего файла на чтение

BinaryReader inBin = new BinaryReader

(File.Open("c:\\temp\\a1.dat", FileMode.Open));

//inBin - созданный нами объект

Атрибут FileMode может быть выбран из следующего списка

FileMode.Append // открыть файл для дозаписи

FileMode.Create // создание нового файла или перезапись существующего

FileMode.Open //открытие существующего файла на чтение

Для завершения работы с файлом используют метод Close.

outBin.Close();

Операции ввода-вывода

Для записи в открытый файл используют метод Write.

outBin.Write(22.4);

outBin.Write("Хелло ворлд!");

outBin.Write(15);

Для чтения данных из открытого файла используют метод Read

Double m = inBin.ReadDouble();

string q = inBin.ReadString();

int j = inBin.ReadInt32();

Для проверки, достигнут ли конец файла при чтении используют метод PeekChar

while ((inBin.PeekChar())>=0)

{

e = inBin.ReadInt32();

Console.WriteLine(e);

}

Специальные операции

Удаление файла выполняется методом Delete объекта File:

string fileName = "c:\\temp\\a1.txt";

File.Delete(fileName);

Проверка существования файла выполняется методом Exist объекта File:

if (File.Exist("c:\\temp\\a1.txt")) {

//программный код, который

//выполнится если файл существует

}

Переименование/перенос файла выполняется методом Move объекта File:

string path = @"c:\temp\MyTest.txt";

string path2 = @"c:\temp\MyTest.bak";

File.Move(path, path2);

Console.WriteLine

("Файл {0} был переименован в {1}.", path, path2);

Примеры

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

static void CreateFile(string filename)

{

BinaryWriter outBin = new BinaryWriter

(File.Open(filename, FileMode.Create));

Console.Write("Введите количество элементов для записи в файл ");

string s = Console.ReadLine();

int n = Convert.ToInt32(s);

for (int i = 1; i <= n; i++)

{

Console.Write("Введите {0}-й элемент файла ",i);

s = Console.ReadLine();

int m = Convert.ToInt32(s);

outBin.Write(m);

}

outBin.Close();

}

static int FindMax(string filename)

{

BinaryReader inBin = new BinaryReader

(File.Open(filename, FileMode.Open));

int e , i,max,maxnum;

e=i = maxnum = max = 0;

while ((inBin.PeekChar())>=0)

{

e = inBin.ReadInt32();

if (i > 0)

if (e > max) { max = e; maxnum = i; }

else ;

else max = e;

i++;

}

inBin.Close();

return maxnum;

}

static void DoNewFile(string filename1,string filename2,int maxnum)

{

BinaryReader inBin = new BinaryReader

(File.Open(filename1, FileMode.Open));

BinaryWriter outBin = new BinaryWriter

(File.Open(filename2, FileMode.Create));

for (int i = 0; i < maxnum; i++)

{

int e = inBin.ReadInt32();

outBin.Write(e);

}

inBin.Close();

outBin.Close();

}

static void PrintFile(string filename)

{

BinaryReader inBin = new BinaryReader

(File.Open(filename, FileMode.Open));

while ((inBin.PeekChar()) >= 0)

{

int e = inBin.ReadInt32();

Console.WriteLine(e);

}

inBin.Close();

}

static void Main(string[] args)

{

CreateFile("c:\\s1.dat");

int mn=FindMax("c:\\s1.dat");

DoNewFile("c:\\s1.dat", "c:\\s2.dat", mn);

PrintFile("c:\\s2.dat");

Console.ReadKey();

}

Текстовые файлы

Установочные и завершающие операции

Используя классы StreamWriter и StreamReader можно создать свои файловые объекты для выполнения различных операций с текстовыми файлами.

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

StreamWriter outStream =

new StreamWriter(@"c:\a1.txt");

//outStream - созданный нами объект

//открытие существующего файла на чтение

StreamReader inStream =

new StreamReader(@"c:\a1.txt");

//inStream - созданный нами объект

Для завершения работы с файлом используют метод Close.

outStream.Close();

inStream.Close();

Операции ввода-вывода

Для записи в открытый файл используют методы Write и Writeline.

outStream.WriteLine(x);

outStream.Write("Z={0}",z);

outStream.Write();

Для чтения строки из открытого файла используют метод ReadLine.

string s = inStream.ReadLine();

Для проверки, достигнут ли конец файла при чтении используют метод Peek или свойство EndOfStream.

while (inStream.Peek()>-1)

{

string s = inStream.ReadLine();

Console.Writeline(s);

}

//равнозначный вариант

while (!inStream.EndOfStream)

{

string s = inStream.ReadLine();

Console.Writeline(s);

}

Для того, чтобы считывать отдельные элементы из строки, её считывают целиком, а затем разбивают на массив элементов с помощью метода Split.

while (inStream.Peek()>-1)

{

string s = inStream.ReadLine();

string[] elements = s.Split( ' ', ',', '.', ':', '\t' );

foreach (string e in elements)

{

if (e != "")

{

int d = Convert.ToInt32(e);

Console.Write("{0} ", d);

}

}

Console.WriteLine();

}

Пример: Транспонировать матрицу, содержащуюся в текстовом файле. Двухмерные массивы использовать нельзя.

using System.IO;

static void enter(string filename)

{

//описываем необходимые переменные

int i, j, M, N; string s;

//вводим число элементов

Console.Write("Введите число строк матрицы N=");

s = Console.ReadLine();

N = Convert.ToInt32(s);

Console.Write("Введите число столбцов матрицы M=");

s = Console.ReadLine();

M = Convert.ToInt32(s);

StreamWriter outStream = new StreamWriter(filename);

//запускаем циклы по всем элементам матрицы

for (i = 0; i < N; i++) //цикл по строкам

{

for (j = 0; j < M; j++) //цикл по столбцам

{

//вводим i,j-ый элемент

Console.Write("Введите элемент матрицы ({0},{1}) ", i + 1, j + 1);

s = Console.ReadLine();

outStream.Write("{0,3} ", s);

}

outStream.WriteLine();

}

outStream.Close();

}

static void transpose(string filename, string filename2)

{

StreamReader inStream = new StreamReader(filename);

int N = 0; int M = 0; int Mmax = 0;

while (inStream.Peek() > -1)

{

string s = inStream.ReadLine();

string[] elements = s.Split(' ');

M = 0;

foreach (string e in elements)

if (e != "")

{

M++;

if (M > Mmax) Mmax = M;

}

N++;

}

inStream.Close();

StreamWriter outStream = new StreamWriter(filename2);

for (int j = 0; j < M; j++) //цикл по столбцам

{

inStream = new StreamReader(filename);

for (int i = 0; i < N; i++) //цикл по строкам

{

string s = inStream.ReadLine();

string[] elements = s.Split(' ');

int k = 0;

foreach (string e in elements)

if (e != "")

{

if (k == j) { outStream.Write("{0,3} ", e); }

k++;

}

}

inStream.Close();

outStream.WriteLine();

}

outStream.Close();

}

static void print(string filename)

{

StreamReader inStream = new StreamReader(filename);

int N = 0; int M = 0; int Mmax = 0;

while (inStream.Peek() > -1)

{

string s = inStream.ReadLine();

Console.WriteLine(s);

}

inStream.Close();

}

static void Main(string[] args)

{

enter(@"c:\a1.txt");

transpose(@"c:\a1.txt", @"c:\a2.txt");

print(@"c:\a2.txt");

Console.ReadKey();

}

Пример №1

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

Решение

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

using System.IO;

...

static void CreateFile(string filename)

{

BinaryWriter outBin = new BinaryWriter

(File.Open(filename, FileMode.Create));

Console.Write("Введите количество элементов для записи в файл ");

string s = Console.ReadLine();

int n = Convert.ToInt32(s);

for (int i = 1; i <= n; i++)

{

Console.Write("Введите {0}-й элемент файла ", i);

s = Console.ReadLine();

int m = Convert.ToInt32(s);

outBin.Write(m);

}

outBin.Close();

}

static bool SortFile(string filename1)

{

string filename2 = filename1 + ".bak";

BinaryReader inBin = new BinaryReader

(File.Open(filename1, FileMode.Open));

BinaryWriter outBin = new BinaryWriter

(File.Open(filename2, FileMode.Create));

bool first = true;

bool perest = false;

int pre = 0;

while ((inBin.PeekChar()) >= 0)

{

int e = inBin.ReadInt32();

if (first) { pre = e; first = false; }

else

{

if (e >= pre) { outBin.Write(pre); pre = e; }

else { outBin.Write(e); perest = true; }

}

}

outBin.Write(pre);

InBin.Close();

outBin.Close();

File.Delete(filename1);

File.Move(filename2, filename1);

return perest;

}

static void PrintFile(string filename)

{

BinaryReader inBin = new BinaryReader

(File.Open(filename, FileMode.Open));

while ((inBin.PeekChar()) >= 0)

{

int e = inBin.ReadInt32();

Console.WriteLine(e);

}

InBin.Close();

}

static void Main(string[] args)

{

CreateFile("c:\\s1.dat");

do

{

} while (SortFile("c:\\s1.dat"));

Console.WriteLine("Упорядоченный файл");

PrintFile("c:\\s1.dat");

Console.ReadKey();

Дан файл целых чисел. Создать два новых файла, первый из которых содержит четные числа из исходного файла, а второй — нечетные (в том же порядке). Если четные или нечетные числа в исходном файле отсутствуют, то соответствующий результирующий файл оставить пустым.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace R2D2 { class Program { static void Chewbacca(string B, string S, string Q) { Int32 i, j, n; Console.Write("Введите количество элементов\n"); n = Convert.ToInt32(Console.ReadLine()); if (n <= 0) { Console.Write("error"); return; } BinaryWriter J = new BinaryWriter (File.Open(B, FileMode.Create)); BinaryWriter Ch = new BinaryWriter (File.Open(S, FileMode.Create)); BinaryWriter Z = new BinaryWriter (File.Open(Q, FileMode.Create)); if ((File.Exists(B)) && (File.Exists(S)) && (File.Exists(Q))) { Console.Write("Введите элементы файла\n"); for (i = 0; i < n; i++) { j = Convert.ToInt32(Console.ReadLine()); J.Write(j); } J.Close(); Console.Write("\n"); BinaryReader F = new BinaryReader (File.Open(B, FileMode.Open)); if (File.Exists(B)) { for (i = 0; i < n; i++) { j = F.ReadInt32(); if (j % 2 == 0) Ch.Write(j); else Z.Write(j); } Ch.Close(); Z.Close(); F.Close(); return; } } Console.Write("File Not Found"); } static void Main(string[] args) { Chewbacca("C:\\a1.dat", "C:\\a2.dat", "C:\\a3.dat"); Console.ReadKey(); } } }

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

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.IO;

namespace R2D2

{

class Program

{

static void blblbl(string B, string S)

{

Int32 i, n; Double a,b,c;

Console.Write("Введите количество элементов\nN=");

n = Convert.ToInt32(Console.ReadLine());

if (n <= 2) { Console.Write("error"); return; }

BinaryWriter J = new BinaryWriter

(File.Open(B, FileMode.Create));

BinaryWriter Y = new BinaryWriter

(File.Open(S, FileMode.Create));

if ((File.Exists(B)) && (File.Exists(S)))

{

Console.Write("введите элементы файла\n");

for (i = 0; i < n; i++)

{

c = Convert.ToDouble(Console.ReadLine());

J.Write(c);

}

J.Close();

BinaryReader F = new BinaryReader

(File.Open(B, FileMode.Open));

if (File.Exists(B))

{

a = F.ReadDouble();

b = F.ReadDouble();

for (i = 2; i < n; i++)

{

c = F.ReadDouble();

if ((b > a) && (b > c))

{

Y.Write(i);

Console.Write(i + " ");

}

a = b; b = c;

}

Y.Close();

F.Close();

return;

}

}

Console.Write("File Not Found");

}

static void Main(string[] args)

{

blblbl("C:\\a1.dat", "C:\\a2.dat");

Console.ReadKey();

}

}

}

2) Дан файл вещественных чисел. Создать файл целых чисел, содержащий длины всех убывающих последовательностей элементов исходного файла. Например, для исходного файла с элементами 1.7, 4.5, 3.4, 2.2, 8.5, 1.2 содержимое результирующего файла должно быть следующим: 3, 2. Последовательность не может иметь длину меньше, чем 2.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.IO;

namespace R2D2

{

class Program

{

static void Chewie(string B, string S)

{

Int32 i, n, j = 1, d = 0; Double a, b;

Console.Write("Введите количество элементов\nN=");

n = Convert.ToInt32(Console.ReadLine());

if (n <= 1) { Console.Write("error"); return; }

BinaryWriter J = new BinaryWriter

(File.Open(B, FileMode.Create));

BinaryWriter Y = new BinaryWriter

(File.Open(S, FileMode.Create));