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

lec

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

РАБОТА С КАТАЛОГАМИ И ФАЙЛАМИ

В пространстве имен System. IO есть четыре класса, предназначенные для работы с физическими файлами и структурой каталогов на дис-

ке: Directory, File, Directorylnfo и Filelnfo. С их помощью можно выполнять создание, удаление, перемещение файлов и каталогов, а также получение их свойств.

Классы Directory и File реализуют свои функции через статические методы. Directorylnfo и Filelnfo обладают схожими возможностями, но они реализуются путем создания объектов соответствующих классов. Классы

Directorylnfo и Filelnfo происходят от абстрактного класса FileSystemlnfo,

который снабжает их базовыми свойствами, описанными в табл.1.

Таблица 1. Свойства класса FileSystemlnfo

Свойство

Описание

Attributes

Получить или установить атрибуты для данного

 

объекта файловой системы. Для этого свойства ис-

 

пользуются значения перечисления FileAttributes

CreationTime

Получить или установить время создания объ-

 

екта файловой системы

Exists

Определить, существует ли данный объект

 

файловой системы

Extension

Получить расширение файла

Full Name

Возвратить имя файла или каталога с указани-

 

ем полного пути

LastAccessTime

Получить или установить время последнего об-

 

ращения к объекту файловой системы

LastWriteTime

Получить или установить время последнего

 

внесения изменении и обьект файловой системы

Name

Возвратить имя файла. Это свойство доступно

 

только для чтения. Для каталогов возвращает имя

 

последнего каталога в иерархии, если это возмож-

 

но. Если пет, возвращает полностью определенное

 

имя

Класс Directory Info содержит элементы, позволяющие выполнять необходимые действия с каталогами файловой системы. Эти элементы перечислены в табл. 2.

Таблица 2. Элементы класса Directorylnfo

Элемент

Описание

Create,

Создать каталог или подкаталог по указанному

CreateSubDIrectory

пути в файловой системе

Delete

Удалить катапог со всем его содержимым

GetDirectories

Возвратить массив строк, представляющих все

 

подкаталоги

GetFiIes

Получить файлы в текущем каталоге в виде

 

массива объектов

класса Filelnfo

 

MoveTo

Переместить каталог и все его содержимое на

251

 

новый адрес в файловой системе

Parent

Возвратить родительский каталог

В листинге 1 приведен пример, в котором создаются два каталога, выводится информация о них и предпринимается попытка удаления каталога.

Листинг 1. Использование класса Directorylnfo

using System; using System.IO;

namespace ConsoleApplication1

{

class Classl

{

static void DirInfo(DirectoryInfo di)

{

// Вывод информации о каталоге

Console.WriteLine("===== Directory Info =====");

Console.WriteLine("FullName: " + di.FullName); Console.WriteLine("Name: " + di.Name); Console.WriteLine("Parent: " + di.Parent); Console.WriteLine("Creation: " + di.CreationTime); Console.WriteLine("Attributes: " + di.Attributes); Console.WriteLine("Root: " + di.Root); Console.WriteLine("=========================");

}

static void Main()

{

DirectoryInfo di1 = new DirectoryInfo(@"c:\MyDir"); DirectoryInfo di2 = new DirectoryInfo(@"c-\MyDir\temp"); try

{

//Создать каталоги di1.Create(); di2.Create();

//Вывести информацию о каталогах

DirInfo(di1);

DirInfo(di2);

//Попытаться удалить каталог

Console.WriteLine("Попытка удалить {0}.", di1.Name); di1.Delete();

}

catch (Exception)

{

Console.WriteLine("Попытка не удалась ");

}

}

}

}

252

Результат работы программы:

=====Directory Info =====

Full Name: c:\MyDir Name: MyDir Parent:

Creation: 30.04.2006 17:14:44 Attributes: Directory

Root: c:\

=====Directory Info =====

Full Name: c:\MyDir\temp Name: temp

Parent: MyDir

Creation: 30.04.2006 17:14:44 Attributes: Directory

Root: c:\

Попытка удалить MyDir. Попытка не удалась

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

di1.Delete( true);

Обратите внимание на свойство Attributes. Некоторые его возможные значения, заданные в перечислении FileAttributes приведены в табл. 3.

Таблица 3. Некоторые значения перечисления FileAttributes

Значение

Описание

Archi ve

Используется приложениями при выполнении ре-

 

зервного копирования, а в некоторых случаях - при

 

удалении старых файлов

Compressed

Файл является сжатым

Di rectory

Объект файловой системы является каталогом

Encrypted

Файл является зашифрованным

Hidden

Файл является скрытым

Normal

Файл находится в обычном состоянии, и для него ус-

 

тановлены любые другие атрибуты. Этот атрибут не мо-

 

жет использоваться с другими атрибутами

OffIine

Файл, расположенный на сервере, кэширован в хра-

 

нилище на клиентском компьютере. Возможно, что дан-

 

ные этого файла уже устарели

ReadOnly

Файл доступен только для чтения

System

Файл является системным

Листинг 2 демонстрирует использование класса Filelnfo для копирования всех файлов с расширением jpg из каталога d:\foto в каталог d:\temp. Метод Exists позволяет проверить, существует ли исходный каталог.

Листинг 2. Копирование файлов using System;

253

using System.IO;

namespace ConsoleApplicationi

{

class Classl

{

static void Main()

{

try

{

string DestName = @"d:\temp\";

DirectoryInfo dest = new DirectoryInfo(DestName); dest.Create(); // создание целевого каталога

DirectoryInfo dir = new DirectoryInfo(@"d:\foto");

if (!dir.Exists) // проверка существования каталога

{

Console.WriteLine("Каталог " + dir.Name + " не существует"); return;

}

FileInfo[] files = dir.GetFiles("*.jpg"); //список файлов foreach (FileInfo f in files)

f.CopyTo(dest + f.Name); // копирование файлов

Console.WriteLine("Скопировано " + files.Length + " jpg-файлов");

}

catch (Exception e)

{

Console.WriteLine("Error: " + e.Message);

}

}

}

}

Использование классов File и Directory аналогично, за исключением того, что их методы являются статическими и, следовательно, не требуют создания объектов.

Класс FileStream реализует эти элементы для работы с дисковыми файлами. Для определения режимов работы с файлом используются стандартные перечисления FileMode, FileAccess и FileShare. Значения этих перечислений приведены в табл. 11.2—11.4.

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

Листинг 3. Пример использования потока байтов

using System; using System.IO; class Class1

{

static void Main()

254

{

FileStream f = new FileStream("test.txt",

FileMode.Create, FileAccess.ReadWrite);

f.WriteByte(100);

// в начало файла записывается число 100

byte[] x = new byte[10];

 

for (byte i = 0; i < 10; ++i)

 

{

 

 

x[i] = (byte)(10 - i);

 

f.WriteByte(i);

// записывается 10 чисел от 0 до 9

}

 

 

f.Write(x, 0, 5);

 

// записывается 5 элементов массива

byte[] у = new byte[20];

 

f.Seek(0, SeekOrigin.Begin);

// текущий указатель - на начало

f.Read(у, 0, 20);

 

// чтение из файла в массив

foreach (byte elem in у) Console.Write(" " + elem);

Console.WriteLine();

 

 

f.Seek(5, SeekOrigin.Begin);

// текущий указатель - на 5-й элемент

int a = f.ReadByte();

 

// чтение 5-го элемента

Console.WriteLine(a);

 

 

a = f.ReadByte();

// чтение 6-го элемента

Console.WriteLine(a);

 

 

Console.WriteLine("Текущая позиция в потоке" + f.Position); f.Close();

}

}

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

...\ConsoleApplication1\bin\Debug.

Листинг 4. Вывод в текстовый файл

using System; using System.IO; class Class2

{

static void Main()

{

try

{

255

StreamWriter f = new StreamWriter("text.txt"); f.WriteLine("Вывод в текстовый файл:"); double a = 12.234;

int b = 29;

f.WriteLine(" a = {0.6:C} b = {1.2:X}", a, b); f.Close();

}

catch (Exception e)

{

Console.WriteLine("Error: " + e.Message); return;

}

}

}

В листинге 5 файл, созданный в предыдущем листинге, выводится на экран.

Листинг 5. Чтение текстового файла

using System; using System.IO; class Class4

{

static void Main()

{

try

{

StreamReader f = new StreamReader("text.txt"); string s = f.ReadToEnd(); Console.WriteLine(s);

f.Close();

}

catch (FileNotFoundException e)

{

Console.WriteLine(e.Message);

Console.WriteLine(" Проверьте правильность имени файла! "); return;

}

catch (Exception e)

{

Console.WriteLine("Error: " + e.Message); return;

}

}

}

В этой программе весь файл считывается за один прием с помощью метода ReadToEnd(). Чаще возникает необходимость считывать файл построчно, такой пример приведен в листинге 6. Каждая строка при выводе предваряется номером.

Листинг 6. Построчное чтение текстового файла

256

using System; using System.IO; class Class5

{

static void Main()

{

try

{

StreamReader f = new StreamReader("text.txt"); string s;

long i = 0;

while ((s = f.ReadLine()) != null) Console.WriteLine("{0}: {1}", ++i, s);

f.Close();

}

catch (FileNotFoundException e)

{

Console.WriteLine(e.Message); Console.WriteLine("Проверьте правильность имени файла!"); return;

}

catch (Exception e)

{

Console.WriteLine("Error: " + e.Message); return;

}

}

}

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

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

Листинг 7. Преобразования строк в числа

using System; using System.IO; class Class6

{

static void Main()

{

try

{

StreamReader f = new StreamReader("numbers.txt"); string s;

const int n = 20;

257

int[] a = new int[n]; string[] buf;

while ((s = f.ReadLine()) != null)

{

buf = s.Split(' '); long sum = 0;

for (int i = 0; i < buf.Length; ++i)

{

a[i] = Convert.ToInt32(buf[i]); sum += a[i];

}

Console.WriteLine("{0} сумма: {1}", s, sum);

}

f.Close();

}

catch (FileNotFoundException e)

{

Console.WriteLine(e.Message);

Console.WriteLine(" Проверьте правильность имени файла!"); return;

}

catch (Exception e)

{

Console.WriteLine("Error: " + e.Message); return;

}

}

}

Результат работы программы: 12 4 сумма: 7 3 44 -3 6 сумма: 50 8 1 1 сумма: 10

В листинге 8 приведен пример формирования двоичного файла. В файл записывается последовательность вещественных чисел, а затем для демонстрации произвольного доступа третье число заменяется чис-

лом 8888.

Листинг 8. Формирование двоичного файла

using System; using System.IO; class Class7

{

static void Main()

{

try

{

BinaryWriter fout = new BinaryWriter(

new FileStream(@"D:\C#\binary", FileMode.Create));

258

double d = 0;

while (d < 4)

{

fout.Write(d); d += 0.33;

}

fout.Seek(16, SeekOrigin.Begin); // второй элемент файла fout.Write(8888d);

fout.Close();

}

catch (Exception e)

{

Console.WriteLine("Error: " + e.Message); return;

}

}

}

При создании двоичного потока в него передается объект базового потока. При установке указателя текущей позиции в файле учитывается длина каждого значения типа doubl e — 8 байт.

Попытка просмотра сформированного программой файла в текстовом редакторе весьма медитативная, но не информативная, поэтому в листинге 9 приводится программа, которая с помощью экземпляра BinaryReader считывает содержимое файла в массив вещественных чисел, а затем выводит этот массив на экран. При чтении принимается во внимание тот факт, что метод ReadDouble при обнаружении конца файла генерирует исключение EndOfStreamException. Поскольку в данном случае это не ошибка, тело обработчика исключений пустое.

Листинг 9. Считывание двоичного файла

using System; using System.IO; class Class8

{

static void Main()

{

try

{

FileStream f = new FileStream(@"D:\C#\binary", FileMode.Open);

BinaryReader fin = new BinaryReader(f);

long n = f.Length / 8; // количество чисел в файле double[] x = new double[n];

long i = 0;

try

 

{

 

while (true) x[i++] = fin.ReadDouble();

// чтение

}

 

catch (EndOfStreamException e) { }

 

259

foreach (double d in x) Console.Write(" " + d); // вывод

fin.Close();

f.Close();

}

catch (FileNotFoundException e)

{

Console.WriteLine(e.Message); Console.WriteLine("Проверьте правильность имени файла!"); return;

}

catch (Exception e)

{

Console.WriteLine("Error: " + e.Message); return;

}

}

}

Результат работы программы:

0 0,33 8888 0,99 1,32 1,65 1,98 2,31 2,64 2,97 3,3 3,63 3.96

260

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