Предисловие Один из создателей проекта Apple Macintosh. Джеф Раскин ( 09.03.1943 - 26.02.2005) (JEF RASKIN) выдвинул на мой взгляд совершенно правильный лозунг Your Time Is Sacred; Your Work Is Sacred – из этого следует, что в обязательном порядке необходимо сохранять проделанную работу – она священна, и время, на нее потраченное, бесценно. [Jef Raskin. THE HUMAN INTERFACE. Chapter 1.6]. Порядок разработки программы. В нашем случае мы хотим написать программу, которая с определенной периодичностью копирует данные в какое-то место, где хранятся архивы. Программу назовём AJefRaskinBuckup – это должно быть консольное приложение, запускаемое из Scheduler’а – Start=>Control Panel=>Scheduler (Пуск=>Панель Управления=>Назначенные задания). Теперь можно начинать писать программу. Шаг № 1 – пишем болванку Hello JefRaskinBuckup using System; class AJefRaskinBuckUp { static void Main(string[] args) { Console.WriteLine(“Hello JefRaskinBuckup”); } } C:\WINDOWS\Microsoft.NET\Framework\v3.5\ csc.exe JefRaskinBuckUp.cs JefRaskinBuckUp.exe Hello JefRaskinBuckup «Приблизительно каждый час я создаю резервную копию своей работы с помощью энергонезависимого запоминающего, которое может быть физически извлечено из компьютера и таким образом защищено от любых неожиданностей в его работе. Кроме того, каждую неделю я сохраняю резервную копию своей системы на внешнем диске. Это не значит, что я параноик, - я всего лишь считаю, что такой подход практичен… Система должна рассматривать данные, вводимые пользователем, как бесценные.» Шаг № 2 – преобразуем болванку Hello JefRaskinBuckup в соответствии с объектно-ориентированной концепцией using System; class AJefRaskinBuckUp { static void Main(string[] args) { AJefRaskinBuckUp p = new AJefRaskinBuckUp(); p.Run(); } void Run() { Console.WriteLine("JefRaskinBuckup "); Console.ReadKey(); } } Шаг № 3 Создадим класс для хранения этих данных о BuckUp’е – что копировать, куда копировать: public class AData { public DateTime dtLastBuckUp; public string sSourceDir; public string[] sDestDir; You first C# Console Program by Yaroshevich A.O 4:1 public AData() { dtLastBuckUp = DateTime.Now; sSourceDir= "F:\\BuckUp\\Last\\"; sDestDir= new string[]{"F:\\_A\\Gegel", "F:\\_E\\12.studentweb.cc"}; } } Создать экземпляр этого класса: AData aD = new AData(); и ставим его в Run() void Run() { AData aD = new AData(); foreach(string s in aD.sSourceDir) {Console.WriteLine(s);} Шаг № 4. Теперь пишем функцию обработчик папок – сначала болванку, и проверяем, как она работает using System.IO; public class AData { ……………………………………………………………………………………………. public void AProcessDirs() { for (int j = 0; j < this.sSourceDir.Length; j++) { DirectoryInfo oD = new DirectoryInfo(this.sSourceDir[j]); Console.WriteLine("DIR:{0}\n", oD.FullName.ToString()); } } } Если печатает название папок, которые необходимо копировать – то все нормально. DIR: F:\\_A\\Gegel DIR: F:\\_E\\12.studentweb.cc Если нет – найти, в чем ошибка. Шаг № 5. Добавляем функционал к функции AProcessDirs() – постараемся обработать все файлы в ней. Для удобства всю обработку поместим в функцию, которая вызывается из функции void AProcessDirs() { for(int j=0;j<i;j++) { DirectoryInfo oD = new DirectoryInfo(aD.sSourceDir[j]); Console.WriteLine("DIR:{0}\n",oD.FullName.ToString()); ACopyFilesFromDirToDest(oD); } } void ACopyFilesFromDirToDest(DirectoryInfo oD) { foreach (FileInfo f in oD.GetFiles()) { Console.WriteLine("Filename: {0}", f.FullName); } } Шаг № 6. Файлы вообще-то надобно не выводить, а копировать. Поэтому напишем функцию, которая копирует файл в нужную папку, и вызовем ее из функции ACopyFilesFromDirToDest void ACopyFileToBuckUp(FileInfo f) { string s = ""; s = this.sDestDir + "\\" + f.DirectoryName.Substring(3); //отрезается имя диска, например С:\Education - c:\ s += '\\' + f.Name; f.CopyTo(s,true); } Запускаем программу –все работает, за исключением одного но… если папки нет – выдается ошибка. Шаг № 7. Для обработки вложенных папок, мы запускаем старую добрую рекурсию. Пишем функцию AProcessDirs(d)- которой передаётся You first C# Console Program by Yaroshevich A.O 4:2 параметр той папки, которую надо обработать и запуская, смотрим, хорошо ли она работает. void AProcessDirs() { for(int j=0;j<i;j++) { DirectoryInfo oD = new DirectoryInfo(aD.sSourceDir[j]); Console.WriteLine("DIR:{0}\n",oD.FullName.ToString()); ACopyFilesFromDirToDest(oD); foreach (DirectoryInfo d in oD.GetDirectories()) { AProcessDirs(d); } } } void AProcessDirs(DirectoryInfo oD) { ACopyFilesFromDirToDest(oD); foreach (DirectoryInfo d in oD.GetDirectories()) { AProcessDirs(d); } } Думаю Вы сразу же заметите, что она работает, но не очень хорошо. Иногда все нормально, а иногда «апшипки» случаются. Может попытаться словить эти апшипки с помощью блока try {} catch Шаг № 8. Помещаем блок try-catch в функцию копирования файлов void ACopyFileToBuckUp(FileInfo f) { string s = ""; s = aD.sDestDir + "\\" + f.DirectoryName.Substring(3); s += '\\' + f.Name; try { f.CopyTo(s, true); } catch (Exception e) { Console.WriteLine("ОШИБКА:{0}\n", e.Message); } } Запускаем – ага, всё ясно. Вложенной папки – куда копировать – нет. Создаём ее с помощью специально написанной для этого случая функции, которая создает несуществующую папку. Шаг № 9. Пишем функцию создания папки в архиве, если её не существует, конечно void ACopyFileToBuckUp(FileInfo f) { string s = ""; s = aD.sDestDir + "\\" + f.DirectoryName.Substring(3); ATestDir(s); s += '\\' + f.Name; try { f.CopyTo(s, true); } catch (Exception e) { Console.WriteLine("ОШИБКА:{0}\n", e.Message); } } void ATestDir(string s) { DirectoryInfo d = new DirectoryInfo(s); if (d.Exists) return; d.Create(); return; } You first C# Console Program by Yaroshevich A.O 4:3 BLOBs Шаг. 10. Создать БД и таблицу для хранения значений. Можно сделать хитрее – сделать такую таблицу в учебной БД Northwind.mdb – которая установлена на каждом комьютере в папке C:\Program Files\Microsoft Office\OFFICE11\SAMPLES\ Никто не догадается, что там м.б. сокрыта значимая информация. В поле FileName будет содержаться информация о имени файла В поле DocumentFile – сам файл Шаг 11. В программе AJefRaskinBuckup создать новый метод ASaveBlobToDatabase: void ASaveBlobToDatabase(FileInfo f) { } ASaveBlobToDatabase(f); //f.CopyTo(s, true); Этот метод будет Шаг 12. Записываем в метод ASaveBlobToDatabase код по чтению файла в массив байтов void ASaveBlobToDatabase(FileInfo f) { byte[] aBLOB; FileStream fs = new FileStream(f.FullName, FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fs); aBLOB = br.ReadBytes((int)f.Length); br.Close(); fs.Close(); Шаг 13. Вносим код, осуществляющий запись в БД. void ASaveBlobToDatabase(FileInfo f) { OleDbConnection aOLEDBConnection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source= C:\\... Northwind.mdb"); // Создать поля для сохранения значений BLOB. OleDbCommand aSaveDocCommand = new OleDbCommand(); aSaveDocCommand.Connection = aOLEDBConnection; aSaveDocCommand.CommandText = "INSERT INTO tblDocStorage" + "(FileName, DocumentFile)" + "VALUES (@FileName, @DocumentFile)"; // создать параметры для запоминания имени файла и BLOB данных OleDbParameter aFileNameParameter = new OleDbParameter("@FileName", OleDbType.Char); OleDbParameter aDocumentFileParameter = new OleDbParameter("@DocumentFile", OleDbType.Binary); aSaveDocCommand.Parameters.Add(aFileNameParameter); aSaveDocCommand.Parameters.Add(aDocumentFileParameter); // Назначить параметру имя файла aFileNameParameter.Value = f.Name; // Назначить BLOB параметру. aDocumentFileParameter.Value = aBLOB; // Выполнить команду и сохранить BLOB в базе д-х try { aSaveDocCommand.Connection.Open(); aSaveDocCommand.ExecuteNonQuery(); Console.WriteLine(aFileNameParameter.Value.ToString() + " сохранён в БД. как BLOB Saved!"); } catch (Exception ex) { Console.WriteLine(ex.Message+ " Сохранение неуспешно :("); } finally { aSaveDocCommand.Connection.Close(); } } Шаг 14. Запустить программу исправить ошибки. Если все пройдет правильно, то таблица станет выглядеть так: Замечательно, что объект просто так не откроешь, дорвавшись до БД – необходимо раскодировать. You first C# Console Program by Yaroshevich A.O 4:4