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. Этот класс не является наследником потоковых классов.
|
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.
Форматы методов:
У всех перечисленных ниже методов параметр 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
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) = ???
Файлы с прямым доступом:
Способ 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() следующая операция чтения или записи данных будет выполняться на новой позиции в файле.
Исключение |
|
Описание |
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 в |
нач.файла
для 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;
}
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