Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

lec

.pdf
Скачиваний:
24
Добавлен:
24.03.2015
Размер:
3.43 Mб
Скачать

Console.WriteLine(exc.Message + "\nHe удается открыть файл."); return;

}

try

{

dataOut.Write(i);

dataOut.Write(d);

dataOut.Write(b); dataOut.Write(12.2 * 7.4);

}

catch (IOException exc)

{

Console.WriteLine(exc.Message + "\nОшибка при записи.");

}

dataOut.Close();

// Теперь попробуем прочитать эти данные. try

{

fs = new FileStream("testdata", FileMode.Open); dataIn = new BinaryReader(fs);

}

catch (FileNotFoundException exc)

{

Console.WriteLine(exc.Message + "\nHe удается открыть файл."); return;

}

try

{

i = dataIn.ReadInt32();

d = dataIn.ReadDouble(); b = dataIn.ReadBoolean(); d = dataIn.ReadDouble();

}

catch (IOException exc)

{

Console.WriteLine(exc.Message + "Ошибка при считывании.");

}

dataIn.Close(); Console.WriteLine("Прочитали " + i); Console.WriteLine("Прочитали " + d); Console.WriteLine("Прочитали " + b); Console.WriteLine("Прочитали " + d);

}

}

3. Непотоковый файловый ввод-вывод (2005)

Предоставляется статическим классом File. Этот класс не является наследником потоковых классов.

181

 

public

static class

File

 

 

 

Методы ввода/вывода:

 

 

 

 

 

 

 

Opens a binary file, reads the contents of

 

 

ReadAllBytes

the file into a byte array, and then closes

 

 

 

 

the file.

 

 

 

 

 

 

 

 

 

 

ReadAllLines

Opens a text file, reads

all lines of

the

 

 

(String)

 

 

 

 

file, and then closes the file.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ReadAllLines

Opens a file, reads all

lines of the

file

 

 

with the specified encoding, and then closes

 

 

(String, Encoding)

 

 

the file.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ReadAllText

Opens a text file, reads all lines of the

 

 

(String)

 

file, and then closes the file.

 

 

 

 

 

 

 

 

 

ReadAllText (String,

Opens a file, reads all lines of the file

 

 

with the specified encoding, and then closes

 

 

Encoding)

 

the file.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Creates a new file, writes the specified

 

 

WriteAllBytes

byte array to the file, and

then closes

the

 

 

file. If the target file already exists, it is

 

 

 

 

 

 

 

 

overwritten.

 

 

 

 

 

 

 

 

 

 

 

Creates a new file, write the specified

 

 

WriteAllLines

string array to the file, and then closes the

 

 

(String, String[ ])

file. If the target file already exists, it is

 

 

 

 

overwritten.

 

 

 

 

 

 

 

 

 

WriteAllLines

Creates a new file, writes the specified

 

 

string array to the file using the specified

 

 

(String,

String[],

 

 

Encoding)

 

encoding, and then closes

the file. If

the

 

 

 

target file already exists, it is overwritten.

 

 

 

 

 

 

 

 

 

 

 

 

 

Creates a new file, writes the specified

 

 

WriteAllText

string to the file, and then closes the file.

 

 

 

(String, String)

If the target file already exists, it is

 

 

 

 

overwritten.

 

 

 

 

 

 

 

 

 

WriteAllText

Creates a new file, writes the specified

 

 

string to the file using the specified encod-

 

 

(String,

String,

 

 

Encoding)

 

ing, and then closes the file. If the target file

 

 

 

already exists, it is overwritten.

 

 

 

 

 

 

 

 

 

 

 

 

 

Другие методы:

 

 

 

 

 

Exists

 

Determines whether the specified file exists.

 

Overloaded. Appends the specified stringto AppendAllText the file, creating the file if it does not already ex-

ist.

Форматы методов:

182

У всех перечисленных ниже методов параметр path определяет путь к файлу

public static byte[ ] public static string[ ] public static string

public static void public static void public static void

ReadAllBytes ( string path )

ReadAllLines ( string path )

ReadAllText ( string path )

WriteAllBytes ( string path, byte[ ] bytes ) WriteAllLines ( string path, string[ ] contents ) WriteAllText ( string path, string contents )

Методы открывают файл, выполняют чтение/запись всего файла, а затем закрывают файл. И это все – одним вызовом.

Методы Write… перезаписывают старые файлы и создают их, если они не существовали.

Для методов Read… файлы должны существовать.

Метод WriteAllLines дописывает символы конца строки. При записи другими методами необходимо добавить символы конца строки вручную:

"\r\n" или Environment.NewLine.

Метод ReadAllLines разделяет строки по символам их конца.

Методы ReadAllLines и ReadAllBytes автоматически устанавливают размерность массива по фактическому количеству считанных элементов (строк, байтов).

Методы ReadAllText и WriteAllText работают с содержимым файла как с одной строкой, не реагируя на символы конца строк.

Таблица исключений для метода ReadAllLines:

Exception type

Condition

 

 

ArgumentException

path is a zero-length string, contains

 

only white space, or contains one or more

 

invalid characters as defined by

 

InvalidPathChars.

 

 

ArgumentNullException

path is a null reference.

 

 

PathTooLongException

The specified path, file name, or both

 

exceed the system-defined maximum

 

length. For example, on Windows-based

 

platforms, paths must be less than 248

 

characters, and file names must be less

 

than 260 characters.

 

 

DirectoryNotFoundException

The specified path is invalid (for exam-

 

ple, it is on an unmapped drive).

 

 

IOException

An I/O error occurred while opening

 

the file.

 

 

 

183

UnauthorizedAccessException

path specified a file that is read-only.

 

-or-

 

This operation is not supported on the

 

current platform.

 

-or-

 

path specified a directory.

 

-or-

 

The caller does not have the required

 

permission.

 

 

FileNotFoundException

The file specified in path was not

 

found.

 

 

NotSupportedException

path is in an invalid format.

 

 

SecurityException

The caller does not have the required

 

permission.

 

 

Пример использования методов WriteAllLines, ReadAllLines, AppendAllText и Exists:

using System; using System.IO; class Test

{

public static void Main()

{

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

// Текст добавляется в файл только один раз if ( ! File.Exists (path) )

{

// Создать файл и записать строки. Закрыть файл. string[ ] createText = { "Hello", "And", "Welcome" }; File.WriteAllLines (path, createText);

}

//Этот текст будет добавляться при каждом запуске программы string appendText = "This is extra text" + Environment.NewLine; File.AppendAllText (path, appendText);

//Открыть файл, прочитать и закрыть.

string[] readText = File.ReadAllLines (path);

foreach (string s in readText)

{

Console.WriteLine(s);

}

}

}

Hello

And Welcome

This is extra text This is extra text

184

This is extra text

Пример использования методов WriteAllText и ReadAllText. using System;

using System.IO; using System.Text;

class Test

{

public static void Main()

{

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

if (!File.Exists(path))

{

// Создать файл и записать текст. Закрыть файл.

string createText = "Hello and Welcome" + Environment.NewLine; File.WriteAllText (path, createText);

}

string appendText = "This is extra text" + Environment.NewLine; File.AppendAllText(path, appendText);

// Открыть файл, прочитать и закрыть. string readText = File.ReadAllText(path); Console.WriteLine(readText);

}

}

Hello and Welcome

This is extra text

This is extra text

4. Файлы с последовательным и прямым доступом Файлы с последовательным доступом:

\ r \ n

Указатель позиции

 

 

 

Зап. 1

 

Запись 2

 

3

 

4

 

Зап. 5

 

• • •

 

Зап. N

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

рис.3

Адр(запись i) = ???

185

Файлы с прямым доступом:

Способ 1.

Указатель поз.

0

 

Запись 1

 

Запись 2

 

• • •

 

Запись N

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

рис.4

Length(Запись 1) = Length(Запись 2) = Length(Запись N)=const

Адр(Запись i) = Length(Запись) * (i-1) байт

Способ 2. Файл адресов записей: Адр(запись i) = Адр[i-1]

Указатель поз.

• • •

Зап. 1

Запись 2

3

4

Зап. 5

• • •

Зап. N

 

 

 

рис.5

 

 

 

Для доступа к требуемой записи необходимо использовать метод Seek(), определенный в классе FileStream. Этот метод позволяет установить указатель позиции (файловый указатель) в любое место файла.

Формат:

long Seek (long newPos, SeekOrigin origin)

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

Элемент origin может принимать одно из значений, определенных перечислением SeekOrigin:

Значение

Описание

SeekOrigin.Begin

Поиск от начала файла

SeekOrigin.Current

Поиск от текущей позиции

SeekOrigin.End

Поиск от конца файла

После обращению к методу Seek() следующая операция чтения или записи данных будет выполняться на новой позиции в файле.

186

Исключение

 

Описание

IOException

 

Ошибка ввода-вывода

NotSuppotedException

 

Базовый поток не поддерживает

 

 

эту функцию

f = new FileStream ("random.dat", FileMode.Create);

f.Seek(0, SeekOrigin.Begin);

// Переход в начало файла.

f.Seek(4, SeekOrigin.Begin);

// Поиск пятого байта (№ б. = 4).

f.Seek(-10, SeekOrigin.End);

// Поиск одиннадцатого байта от конца.

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

//Записать в файл алфавит прописными буквами,

//а затем выборочно считать его.

using System; using System.IO;

class RandomAccessDemo

{

public static void Main()

{

FileStream f; char ch;

try

{

f = new FileStream ("random.dat", FileMode.Create);

}

catch (IOException exc)

{

Console.WriteLine (exc.Message); return;

}

// Записываем в файл алфавит. for ( int i = 0; i < 26; i++)

{

try

{

f.WriteByte ((byte)('A' + i));

}

catch (IOException exc)

{

Console.WriteLine (exc.Message); return;

}

}

try

{

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

f.Seek (0, SeekOrigin.Begin); // Поиск первого байта. ch = (char)f.ReadByte();

Console.WriteLine("Первое значение равно " + ch);

f.Seek (1, SeekOrigin.Begin); // Поиск второго байта.

187

ch = (char)f.ReadByte(); Console.WriteLine("Второе значение равно " + ch); f.Seek (4, SeekOrigin.Begin); // Поиск пятого байта. ch = (char)f.ReadByte();

Console.WriteLine ("Пятое значение равно " + ch); Console.WriteLine ();

// Теперь считываем значения через одно. Console.WriteLine ("Выборка значений через одно: "); for (int i = 0; i < 26; i += 2)

{

f.Seek (i, SeekOrigin.Begin);

// Переход к i-му байту.

ch = (char)f.ReadByte();

 

Console.Write (ch + " ");

 

}

 

}

 

catch (IOException exc)

 

{

 

Console.WriteLine (exc.Message);

 

}

 

Console.WriteLine();

 

f.Close();

 

}

}

При выполнении этой программы получены такие результаты: Первое значение равно А Второе значение равно В Пятое значение равно Е

Выборка значений через одно: ACEGIKMOQSUWY

Проблемы.

Строки имеют переменную длину (по фактическому содержимому). Решением проблемы м.б.: 1) добаление к строкам пробелов до одинаковой длины методом PadRicht(); 2) преобразование строки в массив сим-

волов методом ToCharArray().

В кодировке, используемой по умолчанию (UTF8), русские буквы кодируются двумя байтами, а английские – одним. Решение проблемы:

указывать кодировку явно, например, System.Text.Encoding.Unicode.

Кодировка текстовых потоков

В C# используются следующие статические свойства класса System.Text.Encoding для кодировки текстовых потоков

Кодировка

Описание

ASCII

Кодировка ASCII без символов кириллицы, в которой

 

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

 

младшие 7 бит байта

Unicode

Кодировка UNICODE. Для представления символов

 

используется 16 бит (т. е. 2 байта). Сигнатура = FF FE в

188

нач.файла

для StreamWriter

UTF7 Кодировка UCS Transformation Format. Применяется для представления символов UNICODE. В ней используются младшие 7 бит данных

UTF8 To же, но для представления символов UNICODE в ней используется 8 бит данных

Default Системная кодировка ANSI (не путайте ее с кодировкой ASCII). В этой кодировке для представления каждого символа используется 8 бит данных

Свойства класса кодировки System.Text.Encoding: ASCII – 1 байт (старший бит = 0);

Default – по умолчанию (UTF8); Unicode – 2 байта;

UTF32 – 4 байта;

UTF7 – 1 байт, старший бит не используется; UTF8 – 1 байт (по умолчанию в ,NET).

Примеры произвольного доступа к записям. Задача 1.

/*

Разработать класс «Студент». Каждый студент определяется полями: Фамилия, имя (тип string);

Год рождения (тип int);

Средний балл за предыдущий год обучения или за вступ. экзамен (тип float).

Создать программу учета студентов группы (в виде массива). Информацию о студентах ввести с клавиатуры. Признаком конца списка является ввод пробела в качестве фамилии студента.

Вывести на экран информацию обо всех студентах.

Информацию обо всех студентах сохранить в файле С:\Temp\GroupDirect.bin с произвольным доступом. Обеспечить постоянную длину всех записей. */

using System; using System.IO;

using System.Collections;

class Student

 

{

 

public string

fio;

public uint

yar;

public float

ball;

public Student(string f, uint y, float b)

{

fio = f; yar = y; ball = b;

}

189

public void Show()

{

Console.WriteLine("Студент {0}, год рождения {1}, ср.балл = {2}", fio, yar, ball);

}

}

class Example1

{

public static void Main()

{

string

fio = " ";

uint

god = 0, n = 1;

float

ball = 0;

Student

std;

BinaryWriter dataOut;

FileStream

fs;

ArrayList tableStd = new ArrayList();

while (true)

{

Console.WriteLine(

"\n____________________Студент {0}____________________________", n);

Console.Write(

"Введите фамилию (не > 15 символов, пробел - конец списка): "); fio = Console.ReadLine();

if (fio == " " || fio.Length == 0) break;

try

{

Console.Write("Введите год рождения: "); god = uint.Parse(Console.ReadLine());

Console.Write("Введите средний балл: "); ball = float.Parse(Console.ReadLine());

}

catch

{

Console.WriteLine("==ОШИБКА== Неверный формат ввода. Повторите!"); continue;

}

std = new Student(fio, god, ball); tableStd.Add(std);

n++;

}

// Таблица создана. выведем ее на экран и сохраним в файле

Console.WriteLine("\n");

try

190

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]