- •Цель работы
- •Общие сведения Класс Environment
- •Работаем со специальными папками
- •Получаем список всех дисков
- •Ввод/вывод в c# (System.Io)
- •Классы для работы с папками и файлами
- •Класс Directory
- •Класс File
- •Класс FileSystemInfo
- •Класс DirectoryInfo
- •Класс DirectoryInfo
- •Перечисление FileAttributes
- •Класс FileInfo
- •Пример: получение имен всех подпапок
- •Класс Path
- •Класс FileSystemWatcher
- •Перечисление NotifyFilters
- •Перечисление WatcherChangeTypes
- •Побайтовое чтение/запись. Чтение текстовых данных
- •Асинхронный доступ к файлам
- •Сетевое программирование
- •Dns класс
- •IpHostEntry класс
- •IpEndPoint класс
- •Класс Socket
- •Протокол udp
- •Шифрование
- •Ход работы
- •Контрольные вопросы
- •Отчетность
- •Дополнительная литература
Асинхронный доступ к файлам
Приложение может выполнять какие-то действия параллельно с процессом ввода/вывода файла, вместо ожидания окончания этого процесса. Процесс считываня файла начинается с вызова метода BeginRead(), методу передаются параметры аналогичные методу Read() + дополнительные, необходимые для осуществления асинхронного процесса.
byte[] byteData = new byte[100];
char[] charData = new char[100];
try
{
FileStream fs = new FileStream("d:\\log.txt", FileMode.Open);
fs.Seek(0, SeekOrigin.Begin); // на начало файла
// начало процедуры асинхронного чтения из файла, первые 3 параметра аналогичные Read()
// 4й пар.-делегат на метод, к.будет вызван по завершению чтения
// 5й пар.-заданный пользов. объект состояния, предназначенный для передачи некой
// строки или данных, позволяющих идентифицир. данную асинхронную операцию
IAsyncResult asResult = fs.BeginRead(byteData, 0, byteData.Length, null, null);
// выполнение друхиг действий паралельно с чтение данных
while (!asResult.IsCompleted) // хранит инф. о сотоянии процесса
{
// другие действия только здесь...
MessageBox.Show("reading from file...");
}
// завершение чтения. передается объект IAsyncResult, возвращенный методом Begin()
fs.EndRead(asResult);
// обработка данных, без нее завершить процесс безсмысленно
Decoder d = Encoding.ASCII.GetDecoder();
d.GetChars(byteData, 0, byteData.Length, charData, 0);
MessageBox.Show(new string(charData));
fs.Close();
}
catch (Exception err)
{
MessageBox.Show(err.Message);
}
Другой, более совершенный, способ осуществления доступа к файлам в асинхронном режиме включает использование метода, возвращающего сообщение (о том что операция завершена).
public class AsyncRead
{
byte[] byteData;
char[] charData;
public AsyncRead()
{
byteData = new byte[1000];
charData = new char[1000];
try
{
FileStream fs = new FileStream("d:\\log.txt", FileMode.Open);
fs.Seek(0, SeekOrigin.Begin); // на начало файла
// делегат указатель на функцию, которая будет обрабатываться
AsyncCallback cb = new AsyncCallback(this.HandleRead);
IAsyncResult aResult = fs.BeginRead(byteData, 0, byteData.Length, cb, "read log.txt");
}
catch (IOException err) { MessageBox.Show(err.Message); }
}
// действия которые будут выполняться по завершению обработки
public void HandleRead(IAsyncResult ar)
{
Decoder d = Encoding.ASCII.GetDecoder();
d.GetChars(byteData, 0, byteData.Length, charData, 0);
MessageBox.Show(new string(charData));
}
…
private void button2_Click(object sender, EventArgs e)
{
AsyncRead ar = new AsyncRead();
// продолжаем основные действия
for (int i = 0; i < 50; i++) { MessageBox.Show(i.ToString()); }
}
Создается экземпляр класса AsyncReader, а заме продолжается выполнение – вывод порядковых чисел на консоль; теперь этому методу не приходиться отслеживать процедуру считывания, и он может выполнять какие-либо другие действия, совершенно от этой процедуры не зависящие. Метод HandleRead вызывается системой, когда завершается процедура считывания файла. Это позволяет приложению продолжать обработку какой-либо иной информации, пока выполняется относительно медленная процедура считывания файла.
Пример:
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.btnOK.Enabled = false;
this.LoadOccupation();
this.txtName.Tag = false;
this.txtAge.Tag = false;
this.txtAddress.Tag = false;
this.txtName.Validating += new CancelEventHandler(this.txtBoxEmpty_Validating);
this.txtAddress.Validating += new CancelEventHandler(this.txtBoxEmpty_Validating);
this.txtAge.Validating += new CancelEventHandler(this.txtBoxEmpty_Validating);
this.txtAge.KeyPress += new KeyPressEventHandler(txtAge_KeyPress);
this.txtName.TextChanged += new EventHandler(txtBox_TextChanged);
this.txtAddress.TextChanged += new EventHandler(txtBox_TextChanged);
this.txtAge.TextChanged += new EventHandler(txtBox_TextChanged);
}
…
private void btnOK_Click(object sender, EventArgs e)
{
string output;
output = "Имя: " + this.txtName.Text + "\r\n";
output += "Адресс: " + this.txtAddress.Text + "\r\n";
output += "Профессия: " + this.cmbOccupation.Text + "\r\n";
output += "Пол: " + (string)(this.rdoMale.Checked ? "Мужской" : "Женский") + "\r\n";
output += "Возраст: " + this.txtAge.Text;
this.txtOutput.Text = output;
}
// чтение из файла
private void LoadOccupation()
{
try
{
// создание объекта StreamReader
System.IO.StreamReader sr = new System.IO.StreamReader("occupation.txt");
string input;
do
{
input = sr.ReadLine(); // построчное чтение
if (input != "") // пропуск пустых строк
this.cmbOccupation.Items.Add(input);
} while (sr.Peek() != -1); // -1 возвращается когда достигнут конец потока
sr.Close();
}
catch (Exception)
{
MessageBox.Show("Файл не найден");
}
}
// запись в файл
private void SaveOccupation()
{
try
{
System.IO.StreamWriter sw = new System.IO.StreamWriter("occupation.txt");
foreach (string item in this.cmbOccupation.Items)
{
sw.WriteLine(item); // запись
}
sw.Flush(); // очистка буфера
sw.Close();
}
catch (Exception)
{
MessageBox.Show("Файл не найден");
}
}
private void ValidateAll()
{
this.btnOK.Enabled = ((bool)(this.txtName.Tag) &&
(bool)(this.txtAddress.Tag) &&
(bool)(this.txtAge.Tag));
}
private void cmbOccupation_KeyDown(object sender, KeyEventArgs e)
{
// если Text отсутствует в семействе Items то добавляем его
int index = 0;
ComboBox cb = (ComboBox)sender;
if (e.KeyCode == Keys.Enter)
{
// осуществ. поиск строки и не является чувствительным к регистру
index = cb.FindStringExact(cb.Text);
if (index < 0)
cb.Items.Add(cb.Text);
else
cb.SelectedIndex = index;
// указывает на то что событие KeyDown нами обработано
e.Handled = true;
}
}
}
}
…
protected override void Dispose(bool disposing)
{
// сохранение элементов
SaveOccupation();
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
