Работа с коллекциями файлов и папок


Чеботарев Игорь

В одной из предыдущих статей затрагивалась тема работы с файловой системой вообще и с файлами и каталогами в частности. Однако, при рассмотрении этого вопроса объяснялось как работать с одним файлом или одним каталогом. Зачастую, этого бывает недостаточно, особенно, когда нужно совершить какие-то действия со всеми файлами из определенного каталога и их имена не известны (довольно распространенная задача). Для этого случая в Windows Script Host есть возможность работы с коллекциями файлов и каталогов.

Сперва рассмотрим работу с каталогами. Список каталогов хранится в коллекции Folders, получить которую можно с помощью свойства SubFolders объекта Folder (может немного запутанно, но в приведенном ниже примере все станет ясно). Folders имеет свойство Count и методы Item и Add. Вот небольшой пример на JScript, выводящий список имен всех папок на диске С:, демонстрирующий как работать с коллекцией Folders:

var fso, f, fc, fc1, s; 
fso = new ActiveXObject("Scripting.FileSystemObject"); 
f = fso.GetFolder("C:"); 
fc = new Enumerator(f.SubFolders); 
fc1 = f.SubFolders; 
s = ""; 

for (; !fc.atEnd(); fc.moveNext()) {
    s += fc.item();
    s += "\n"; 
}

 s = s + "Всего папок: " + fc1.Count; 
WScript.Echo(s);

Аналогично на VBScript:

Dim fso, f, f1, fc, s 
Set fso = CreateObject("Scripting.FileSystemObject") 
Set f = fso.GetFolder("C:") 
Set fc = f.SubFolders 
s = ""

For Each f1 in fc 
   s = s & f1.name 
   s = s & CHR(10) 
Next 

s = s & "Всего папок: " & fc.Count 
WScript.Echo s

Для иллюстрации метода Add приведу небольшой пример на JScript:

var fso, f, fc; 
fso = WScript.CreateObject("Scripting.FileSystemObject"); 
f = fso.GetFolder("C:"); 
fc = f.SubFolders; 
fc.Add("NewFolder");

Этот метод позволяет создать новую папку с именем, заданным в качестве параметра, в указанной вами директории.

Конечно, данные примеры вряд ли найдут практическое применение, но для иллюстрации работы с каталогами этого вполне достаточно. Работа с файлами мало отличается от работы с каталогами. Список всех файлов из какого-либо каталога формируется с помощью коллекции Files. Вот небольшой пример, в принципе, очень похожий на первый:

var fso, f, f1, fc, s; 
fso = new ActiveXObject("Scripting.FileSystemObject"); 
f = fso.GetFolder("C:"); 
fc = new Enumerator(f.files); 
s = ""; 

for (; !fc.atEnd(); fc.moveNext()) { 
   s += fc.item();
   s += "\n"; 
} 

WScript.Echo(s);

И без комментариев все довольно понятно. В конце хотелось бы привести пример, реально встречающийся в практике: синхронизация содержимого двух каталогов. Здесь файлы сравниваются по имени и размеру и если у файлов с одинаковым именем оказываются разные размеры, то происходит копирование файла из одного каталога в другой, а информация об этом сохраняется в логе. Таким способом можно синхронизировать какие-то файлы лежащие на сервере и на локальной машине, просто поменяйте пути к папкам на нужные вам. Скрипт написан на VBScript.

Set fso = CreateObject("Scripting.FileSystemObject") 
Set UFolder = fso.getfolder("C:\Folder1") 
set UFile = UFolder.files 
Set OFolder = fso.getfolder("C:\Folder2") 
Set OFile = OFolder.files 

If (fso.FileExists("C:\LOG\copy.log")) Then 
   Set MyFile = fso.OpenTextFile("C:\LOG\copy.log", 8, True) 
Else 
   Set MyFile = fso.CreateTextFile("C:\LOG\copy.log") 
end if 

For Each f1 in UFile 
   FileToCopy = UFolder&"\"&f1.Name 
   For Each f2 in OFile 
      if f1.Name = f2.Name then 
         if f1.Size = f2.Size then 
         else 
            fso.CopyFile FileToCopy, OFolder&"\"&f1.Name 
            MyFile.WriteLine(Cstr(Date)&" "&Cstr(Time)&" Файл "&f1.Name&" обновлен. Размер "&f1.Size)
         end if 
      end if 
   Next
Next 

MyFile.Close

читать еще по теме