РАБОТА С КАТАЛОГАМИ И ФАЙЛАМИ
В пространстве имен 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
Скачано с www.znanio.ru
Материалы на данной страницы взяты из открытых источников либо размещены пользователем в соответствии с договором-офертой сайта. Вы можете сообщить о нарушении.