РАБОТА С КАТАЛОГАМИ И ФАЙЛАМИ
В пространстве имен 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 | Переместить каталог и все его содержимое на новый адрес в файловой системе |
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("Попытка не удалась ");
}
}
}
}
Результат работы программы:
===== 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;
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()
{
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
{
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. Построчное чтение текстового файла
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;
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));
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) { }
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
Дата добавления: 2019-02-08; просмотров: 782;