Опубликован: 05.08.2010 | Доступ: свободный | Студентов: 2009 / 47 | Оценка: 4.50 / 4.40 | Длительность: 60:26:00
Лекция 5:

Работа с файлами и каталогами

Упражнение 2. Использование атрибутов

Свойство Attributes, наследуемое экземплярными классами DirectoryInfo и FileInfo от класса FileSystemInfo, устанавливает особенность поведения операционной системы по отношению к элементам файловой системы. Оно обеспечивает доступ к двухбайтному базовому слову, каждый бит которого соответствует определенной поведенческой установке, закрепленной за файлом или каталогом.

Метод ToString() свойства Attributes возвращает строку с именами атрибутов элемента, разделенными запятыми. Следующий код распечатывает названия атрибутов всех файлов заданного каталога

static void Main(string[] args)
        {
            String currentDirectory = @"E:\Tmp\XX";//Directory.GetCurrentDirectory();  // Каталог сборки
            //Console.WriteLine(currentDirectory);
            DirectoryInfo directory = new DirectoryInfo(currentDirectory);
            FileInfo[] files = directory.GetFiles(); // Список файлов
            foreach (FileInfo file in files)
            {
                Console.WriteLine("\nАтрибуты файла {0}", file.Name);
                String[] attributes = file.Attributes.ToString().Split(',');
                for (int i = 0; i < attributes.Length; i++)
                    Console.WriteLine(attributes[i].Trim());
            }
    
            Console.ReadLine();
        }

Для работы с атрибутами используются побитовые операции. Элементы перечисления FileAttributes представляют собой слово (2 байта), в котором только один бит равен единице. Их можно считать побитовыми масками, с помощью которых можно установить или прочитать атрибут. Некоторые атрибуты не могут быть установлены программно. Например, атрибуты FileAttributes. Encrypted и FileAttributes.Compressed устанавливаются самой операционной системой через специальные механизмы.

Прежде, чем двигаться дальше, вспомним поразрадные операции C#. Они позволяют работать с данными на уровне бит. Все поразрядные операции используются только с целыми типами данных ( byte, sbyte, int, uint, short, ushort, long, ulong, char, decimal ), у которых в машинном представлении нет плавающей точки.

Существует 6 поразрядных операций, проиллюстрированных в следующих таблицах

Таблица 18.7.
Операция Наименование Описание
& поразрядное И Бит результата устанавливается в 1, если соответствующие биты обеих операндов равны 1
| поразрядное ИЛИ Бит результата устанавливается в 1, если соответствующий бит хотя бы одного операнда равен 1
^ поразрядное ИСКЛЮЧАЮЩЕЕ ИЛИ Бит результата устанавливается в 1, если соответствующиий бит одного и только одного операнда равен 1
~ поразрядное НЕ Унарная операция, которая применяется только к одному операнду. Меняет каждый бит с 1 на 0 и наоборот
<< поразрядный сдвиг влево Сдвигает биты первого операнда влево на количество позиций, заданных вторым операндом. При этом освобождающиеся справа биты заполняются нулями
>> поразрядный сдвиг вправо Сдвигает биты первого операнда вправо на количество позиций, заданных вторым операндом. При этом освобождающиеся слева биты заполняются нулями

Таблица 18.8. Шестнадцатиричное представление байта
binary 0x
0000 0000 0x00
0000 0001 0x01
0000 0010 0x02
0000 0011 0x03
0000 0100 0x04
0000 0101 0x05
0000 0110 0x06
0000 0111 0x07
0000 1000 0x08
0000 1001 0x09
0000 1010 0x0A
0000 1011 0x0B
0000 1100 0x0C
0000 1101 0x0D
0000 1110 0x0E
0000 1111 0x0F

Таблица 18.9. Пример поразрядных операций
a & mask a | mask a ^ mask ~mask
a 1 0 1 1 0 0 1 0 1 0 1 1 0 0 1 0 1 0 1 1 0 0 1 0
mask 1 1 0 0 1 0 1 0 1 1 0 0 1 0 1 0 1 1 0 0 1 0 1 0 1 1 0 0 1 0 1 0
result 1 0 0 0 0 0 1 0 1 1 1 1 1 0 1 0 0 1 1 1 1 0 0 0 0 0 1 1 0 1 0 1
result ^ mask 1 0 1 1 0 0 1 0

Таблица 18.10. Пример операций сдвига
a << 5 a >> 5
a 1 1 0 1 0 0 0 1 1 1 0 0 1 1 1 1 1 1 0 1 0 0 0 1 1 1 0 0 1 1 1 1
result 0 0 1 1 1 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 1 1 1 0

Таблица 18.11. Операции поразрядного присваивания
& = Операция присваивания поразрядного И
| = Операция присваивания поразрядного ИЛИ
^ = Операция присваивания поразрядного исключающего ИЛИ
<< = Операция присваивания сдвига влево
>> = Операция присваивания сдвига вправо

Следующее упражнение иллюстрирует побитовую арифметику с атрибутами.

  • Добавьте к решению FilesAndDirectory проект консольного приложения App2 и назначьте его стартовым в Solution Explorer командой контекстного меню Set as StartUp Project
  • Заполните файл Program.cs следующим кодом
using System;
using System.Collections.Generic;
using System.Text;
    
using System.IO;
    
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            String currentDirectory = @"E:\Tmp\XX";//Directory.GetCurrentDirectory();  // Каталог сборки
            //Console.WriteLine(currentDirectory);
            DirectoryInfo directory = new DirectoryInfo(currentDirectory);
            FileInfo[] files1 = directory.GetFiles("*.txt"); // Список текстовых файлов
    
            // Создаем маску с атрибутами
            FileAttributes mask = FileAttributes.Archive
                | FileAttributes.ReadOnly
                | FileAttributes.System
                | FileAttributes.Offline
                | FileAttributes.NotContentIndexed
                | FileAttributes.Hidden
                | FileAttributes.Temporary
                | FileAttributes.Device;
    
            // Устанавливаем для всех файлов указанные атрибуты 
            foreach (FileInfo file in files1)
            {
                // Добавляем атрибуты
                file.Attributes |= mask;
            }
    
            // Создаем новый объект для чистоты эксперимента и печатаем атрибуты
            FileInfo[] files2 = directory.GetFiles("*.txt"); // Список текстовых файлов
            foreach (FileInfo file in files2)
            {
                Console.WriteLine("\nАтрибуты файла {0}", file.Name);
                String[] attributes = file.Attributes.ToString().Split(',');
                for (int i = 0; i < attributes.Length; i++)
                    Console.WriteLine(attributes[i].Trim());
            }
    
            // Определяем, имеет ли первый файл коллекции files2 атрибут ReadOnly 
            if ((files2[0].Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                Console.WriteLine(Environment.NewLine   // Новая строка
                    + "Файл {0} имеет атрибут ReadOnly", files2[0].Name);
            else
                Console.WriteLine("\n"                  // Новая строка
                    + "Файл {0} не имеет атрибут ReadOnly", files2[0].Name);
    
            // Исключаем из первого объекта добавленные ранее атрибуты
            foreach (FileInfo file in files1)
            {
                // Исключаем атрибуты
                file.Attributes &= ~mask; // Побитовое умножение на инвертированную маску
            }
    
            // Печатаем результат через второй объект
            // Если открыть комментарные скобки - результат будет неверным!!!
            //*
            for (int i = 0; i < files2.Length; i++)
                files2[i].Refresh();    // Приводим в соответствие с состоянием файлов
            //*/
            foreach (FileInfo file in files2)
            {
                Console.WriteLine("\nАтрибуты файла {0}", file.Name);
                String[] attributes = file.Attributes.ToString().Split(',');
                for (int i = 0; i < attributes.Length; i++)
                    Console.WriteLine(attributes[i].Trim());
            }
    
            // Определяем, имеет ли первый файл коллекции files2 атрибут ReadOnly 
            if ((files2[0].Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                Console.WriteLine(Environment.NewLine   // Новая строка
                    + "Файл {0} имеет атрибут ReadOnly", files2[0].Name);
            else
                Console.WriteLine("\n"                  // Новая строка
                    + "Файл {0} не имеет атрибут ReadOnly", files2[0].Name);
    
            Console.ReadLine();
        }
    }
}
  • Запустите приложение - вывод программы для нескольких файлов будет примерно следующим
Атрибуты файла Test.txt
ReadOnly
Hidden
System
Archive
Temporary
Offline
NotContentIndexed
	
Атрибуты файла xx.txt
ReadOnly
Hidden
System
Archive
Temporary
Offline
NotContentIndexed
	
Файл Test.txt имеет атрибут ReadOnly
	
Атрибуты файла Test.txt
Normal
	
Атрибуты файла xx.txt
Normal
	
Файл Test.txt не имеет атрибут ReadOnly

Обратите внимание, что как только мы сняли с файлов все значимые атрибуты, то для них по умолчанию установился атрибут Normal. Следовательно, для проверки того, что файл не имеет атрибутов, достаточно проверить наличие атрибута Normal.

Класс DriveInfo

Экземплярный класс, который извлекает информацию о дисковом устройстве компьютера. Имя устройства задается в конструкторе класса при создании экземпляра и представляет собой строку с символом от " a " до " z " в любом регистре. Ниже приведены члены класса DriveInfo.

Таблица 18.12. Члены класса DriveInfo
Член Описание
TotalFreeSpace Возвращает объем свободного пространства в байтах
AvailableFreeSpace Возвращает объем свободного пространства в байтах, доступного для данного процесса
DriveFormat Свойство возвращает имя файловой системы ( NTFS или FAT32 )
DriveType Возвращает значение одноименного перечисления DriveType:
  • CDRom - устройство оптического диска, такое как CD или DVD-ROM
  • Fixed - фиксированный диск
  • Network - сетевой
  • NoRootDirectory - у диска нет корневого каталога
  • Ram - устройство RAM
  • Removable - сменное устройство хранения данных, такое как флэшка
  • Unknown - тип диска неопределен
IsReady Определяет готовность устройства к чтению или записи. Например, если нет компакт-диска в CD -приводе, свойство IsReady вернет false. Фиксированные устройства всегда готовы
Name Возвращает строку с именем диска, например, C: или E:
RootDirectory Возвращает объект DirectoryInfo с информацией о корневом каталоге диска
TotalSize Получает полный размер пространства памяти на диске
VolumeLabel Свойство, извлекающее или устанавливающее метку тома
GetDrives() Статический метод, который возвращает массив объектов DriveInfo, представляющих все логические устройства данного компьютера

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

Алексей Бабушкин
Алексей Бабушкин

При выполнении в лабораторной работе упражнения №1 , а именно при выполнении нижеследующего кода:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using Microsoft.Xna.Framework.Graphics;

   

namespace Application1

{

    public partial class MainForm : Form

    {

        // Объявим поле графического устройства для видимости в методах

        GraphicsDevice device;

   

        public MainForm()

        {

            InitializeComponent();

   

            // Подпишемся на событие Load формы

            this.Load += new EventHandler(MainForm_Load);

   

            // Попишемся на событие FormClosed формы

            this.FormClosed += new FormClosedEventHandler(MainForm_FormClosed);

        }

   

        void MainForm_FormClosed(object sender, FormClosedEventArgs e)

        {

            //  Удаляем (освобождаем) устройство

            device.Dispose();

            // На всякий случай присваиваем ссылке на устройство значение null

            device = null;       

        }

   

        void MainForm_Load(object sender, EventArgs e)

        {

            // Создаем объект представления для настройки графического устройства

            PresentationParameters presentParams = new PresentationParameters();

            // Настраиваем объект представления через его свойства

            presentParams.IsFullScreen = false; // Включаем оконный режим

            presentParams.BackBufferCount = 1;  // Включаем задний буфер

                                                // для двойной буферизации

            // Переключение переднего и заднего буферов

            // должно осуществляться с максимальной эффективностью

            presentParams.SwapEffect = SwapEffect.Discard;

            // Устанавливаем размеры заднего буфера по клиентской области окна формы

            presentParams.BackBufferWidth = this.ClientSize.Width;

            presentParams.BackBufferHeight = this.ClientSize.Height;

   

            // Создадим графическое устройство с заданными настройками

            device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware,

                this.Handle, presentParams);

        }

   

        protected override void OnPaint(PaintEventArgs e)

        {

            device.Clear(Microsoft.Xna.Framework.Graphics.Color.CornflowerBlue);

   

            base.OnPaint(e);

        }

    }

}

Выбрасывается исключение:

Невозможно загрузить файл или сборку "Microsoft.Xna.Framework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d" или один из зависимых от них компонентов. Не удается найти указанный файл.

Делаю все пунктуально. В чем может быть проблема?