Сценарии WSH позволяют получить полный доступ к файловой системе компьютера, в отличие от JScript- или VBScript-сценариев, внедренных в HTML-страницы, где в зависимости от уровня безопасности, который устанавливается в настройках браузера, те или иные операции могут быть запрещены.
Для работы с файловой системой из сценариев WSH предназначены восемь объектов, главным из которых является
FileSystemObject
. С помощью методов объекта FileSystemObject
можно выполнять следующие основные действия:
□ копировать или перемещать файлы и каталоги;
□ удалять файлы и каталоги;
□ создавать каталоги;
□ создавать или открывать текстовые файлы;
□ создавать объекты
Drive
, Folder
и File
для доступа к конкретному диску, каталогу или файлу соответственно.
С помощью свойств объектов
Drive
, Folder
и File
можно получить детальную информацию о тех элементах файловой системы, с которыми они ассоциированы. Объекты Folder
и File
также предоставляют методы для манипулирования файлами и каталогами (создание, удаление, копирование, перемещение); эти методы в основном копируют соответствующие методы объекта FileSystemObject
.
Кроме этого, имеются три объекта-коллекции:
Drives
, Folders
и Files
. Коллекция Drives
содержит объекты Drive
для всех имеющихся в системе дисков, Folders
— объекты Folder
для всех подкаталогов заданного каталога, Files
— объекты File
для всех файлов, находящихся внутри определенного каталога.
Наконец, из сценария можно читать информацию из текстовых файлов и записывать в них данные. Методы для этого предоставляет объект
TextStream
.
В табл. 5.1 кратко описано, какие именно объекты, свойства и методы могут понадобиться для выполнения наиболее часто используемых файловых операций.
Таблица 5.1. Выполнение основных файловых операций
Операция | Используемые объекты, свойства и методы |
---|---|
Получение сведений об определенном диске (тип файловой системы, метка тома, общий объем и количество свободного места и т.д.) | Свойства объекта . Сам объект создается с помощью метода объекта
|
Получение сведений о заданном каталоге или файле (дата создания или последнего доступа, размер, атрибуты и т.д.) | Свойства объектов и . Сами эти объекты создаются с помощью методов и объекта
|
Проверка существования определенного диска, каталога или файла | Методы , и объекта
|
Копирование файлов и каталогов | Методы и объекта , а также методы и
|
Перемещение файлов и каталогов | Методы и объекта или методы и
|
Удаление файлов и каталогов | Методы и объекта или методы и
|
Создание каталога | Методы или
|
Создание текстового файла | Методы или
|
Получение списка всех доступных дисков | Коллекция , содержащаяся в свойстве
|
Получение списка всех подкаталогов заданного каталога | Коллекция , содержащаяся в свойстве
|
Получение списка всех файлов заданного каталога | Коллекция , содержащаяся в свойстве
|
Открытие текстового файла для чтения, записи или добавления | Методы или
|
Чтение информации из заданного текстового файла или запись ее в него | Методы объекта
|
Перейдем теперь к подробному рассмотрению объектов, используемых при работе с файловой системой.
Объект
FileSystemObject
является основным объектом, обеспечивающим доступ к файловой системе компьютера; его методы используются для создания остальных объектов (Drives
, Drive
, Folders
, Folder
, Files
, File
и TextStream
).
Для создания внутри сценария экземпляра объекта
FileSystemObject
можно воспользоваться методом CreateObject
объекта WScript
:
var FSO = WScript.CreateObject("Scripting.FileSystemObject");
Также можно использовать объект
ActiveXObject
языка JScript (с помощью этого объекта можно работать с файловой системой из сценариев, находящихся внутри HTML-страниц):
var FSO = new ActiveXObject("Scripting.FileSystemObject");
Объект
FileSystemObject
имеет единственное свойство Drives
, в котором хранится коллекция, содержащая объекты Drive
для всех доступных дисков компьютера. Примеры, иллюстрирующие использование свойства Drives
приведены ниже в разд. "Коллекция Drives".
Методы объекта
FileSystemObject
представлены в табл. 5.2.
Таблица 5.2. Методы объекта FileSystemObject
Метод | Описание |
---|---|
|
Добавляет к заданному пути (параметр ) новое имя (параметр ) |
|
Копирует один или несколько файлов из одного места (параметр ) в другое (параметр ) |
|
Копирует каталог со всеми подкаталогами из одного места (параметр ) в другое (параметр ) |
|
Создает новый каталог с именем . Если каталог уже существует, то произойдет ошибка |
|
Создает новый текстовый файл с именем и возвращает указывающий на этот файл объект
|
|
Удаляет файл, путь к которому задан параметром
|
|
Удаляет каталог, путь к которому задан параметром , вместе со всем его содержимым |
|
Возвращает , если заданное параметром устройство существует и в противном случае |
|
Возвращает , если заданный параметром файл существует и в противном случае |
|
Возвращает , если заданный параметром каталог существует и в противном случае |
|
Возвращает полный путь для заданного относительного пути (из текущего каталога) |
|
Возвращает базовое имя (без расширения) для последнего компонента в пути
|
|
Возвращает объект , соответствующий диску, заданному параметром
|
|
Возвращает строку, содержащую имя диска в заданном пути. Если из параметра нельзя выделить имя диска, то метод возвращает пустую строку (" ") |
|
Возвращает строку, содержащую расширение для последнего компонента в пути . Если из параметра нельзя выделить компоненты пути, то возвращает пустую строку (""). Для сетевых дисков корневой каталог (\) рассматривается как компонент пути |
|
Возвращает объект , соответствующий файлу, заданному параметром . Если файл, путь к которому задан параметром , не существует, то при выполнении метода возникнет ошибка |
|
Возвращает имя файла, заданного полным путем к нему. Если из параметра нельзя выделить имя файла, метод возвращает пустую строку ("") |
|
Возвращает объект , соответствующий каталогу, заданному параметром . Если каталог, путь к которому задан параметром , не существует, при выполнении метода возникнет ошибка |
|
Возвращает строку, содержащую имя родительского каталога для последнего компонента в заданном пути. Если для последнего компонента в пути, заданном параметром , нельзя определить родительский каталог, то метод возвращает пустую строку ("") |
|
Возвращает объект для некоторых специальных папок Windows, заданных числовым параметром
|
|
Возвращает случайным образом сгенерированное имя файла или каталога, которое может быть использовано для операций, требующих наличия временного файла или каталога |
|
Перемещает один или несколько файлов из одного места (параметр ) в другое (параметр ) |
|
Перемещает один или несколько каталогов из одного места (параметр ) в другое (параметр ) |
|
Открывает заданный текстовый файл и возвращает объект для работы с этим файлом |
Сами названия методов объекта
FileSystemObject
довольно прозрачно указывают на выполняемые ими действия. Приведем необходимые пояснения и примеры для перечисленных методов.
Для копирования нескольких файлов или каталогов в последнем компоненте параметра
можно указывать групповые символы "?" и "*"; в параметре source
групповые символы недопустимы. Например, следующий пример является корректным кодом:destination
FSO = WScript.CreateObject("Scripting.FileSystemObject");
FSO.CopyFile("с:\\mydocuments\\letters\\*.doc", "с:\\tempfolder\\");
А так писать нельзя:
FSO = WScript.CreateObject("Scripting.FileSystemObject");
FSO.CopyFile("с:\\mydocuments\\*\\R1???97.xls", "с:\\tempfolder");
Необязательный параметр
является логической переменной, определяющей, следует ли заменять уже существующий файл/каталог с именем overwrite
destination
(overwrite=true
) или нет (overwrite=false
).
При использовании методов
CopyFile
и CopyFolder
процесс копирования прерывается после первой возникшей ошибки (как и в команде COPY
операционной системы).
Параметр
, используемый в методе, имеет значение в том случае, когда создаваемый файл уже существует. Если overwrite
overwrite
равно true
, то такой файл перепишется (старое содержимое будет утеряно), если же в качестве overwrite
указано false
, то файл переписываться не будет. Если этот параметр вообще не указан, то существующий файл также не будет переписан.
Параметр
является логическим значением, указывающим, в каком формате (ASCII или Unicode) следует создавать файл. Если unicode
равно unicode
true
, то файл создается в формате Unicode, если же unicode
равно false
или этот параметр вообще не указан, то файл создается в режиме ASCII.
Для дальнейшей работы с созданным файлом, т.е. для записи или чтения информации, нужно использовать методы объекта
TextStream
. Соответствующий пример сценария приведен в листинге 5.1.
/*******************************************************************/
/* Имя: CreateFile.js */
/* Язык: JScript */
/* Описание: Создание текстового файла и запись в него строки */
/*******************************************************************/
var FSO,f; //Объявляем переменные
//Создаем объект FileSystemObject
FSO = WScript.CreateObject("Scripting.FileSystemObject");
//Создаем на диске C: текстовый файл TestFile.txt
f = FSO.CreateTextFile("C:\\TestFile.txt", true);
//Записываем строку в файл
f.WriteLine("Привет!");
//Закрываем файл
f.Close();
/************* Конец *********************************************/
Параметры
или filespec
, используемые в методах, могут содержать групповые символы "?" и "*" в последнем компоненте пути для удаления сразу нескольких файлов/каталогов.folderspec
Если параметр
равен force
false
или не указан вовсе, то с помощью методов DeleteFile
или DeleteFolder
будет нельзя удалить файл/каталог с атрибутом "только для чтения" (read-only). Установка для force
значения true
позволит сразу удалять такие файлы/каталоги.
При использовании метода
DeleteFolder
неважно, является ли удаляемый каталог пустым или нет — он удалится в любом случае
Если заданный для удаления файл/каталог не будет найден, то возникнет ошибка.
Для дисководов со съемными носителями метод
DriveExists
вернет true
даже в том случае, если носитель физически отсутствует. Для того чтобы определить готовность дисковода, нужно использовать свойство IsReady
соответствующего объекта Drive
.
В качестве примера использования метода
DriveExists
приведем функцию ReportDriveStatus
, которая возвращает информацию о наличии диска, передаваемого в эту функцию в качестве параметра (листинг 5.2).
ReportDriveStatus
function ReportDriveStatus(drv) {
var FSO, s ="" //Объявляем переменные
//Создаем объект FileSystemObject
FSO = WScript.CreateObject("Scripting.FileSystemObject");
//Проверяем наличие диска drv
if (FSO.DriveExists(drv)) s += "Диск " + drv + " существует.";
else s += "Диск " + drv + " не существует.";
return(s);
}
Функция
ReportDriveStatus
будет возвращать информацию о наличии диска, передаваемого в эту функцию в качестве параметра.
Для иллюстрации работы этого метода предположим, что текущим каталогом является C:\MyDocuments\Reports. В табл. 5.3 приведены значения, возвращаемые методом
GetAbsolutePathName
, при различных значениях параметра pathspec
.
Таблица 5.3. Варианты работы метода GetAbsolutePathName
Параметр
|
Возвращаемое значение |
---|---|
|
|
|
|
|
|
|
|
|
|
Работу этого метода иллюстрирует сценарий BaseName.js, приведенный в листинге 5.3. В результате выполнения этого сценария на экран выводится диалоговое окно, в котором отражены полный путь к файлу и базовое имя, выделенное из этого пути (рис. 5.1).
Рис. 5.1. Полный путь к файлу и базовое имя для этого пути
/*******************************************************************/
/* Имя: BaseName.js */
/* Язык: JScript */
/* Описание: Создание текстового файла и запись в него строки */
/*******************************************************************/
var FSO, BaseName, SPath,s; //Объявляем переменные
//Создаем объект FileSystemObject
FSO = WScript.CreateObject("Scripting.FileSystemObject");
//Задаем путь к файлу
SPath="C:\\Мои документы\\letter.txt";
//Выделяем базовое имя файла (без расширения)
BaseName = FSO.GetBaseName(SPath);
//Выводим на экран путь и базовое имя
s="Путь: "+SPath+"\n";
s+="Базовое имя: "+BaseName;
WScript.Echo(s);
/************* Конец *********************************************/
Параметр
в данном методе может задаваться одной буквой (например, "drivespec
С
"), буквой с двоеточием ("С:
"), буквой с двоеточием и символом разделителя пути ("С:\\
"). Для сетевого диска drivespec можно указывать в формате UNC (например, "Server1\\Programs
").
Если параметр
указывает на несуществующий диск или задан в неверном формате, то при выполнении метода drivespec
GetDrive
возникнет ошибка.
Если вам требуется преобразовать строку, содержащую обычный путь к файлу или каталогу, в вид, пригодный для
GetDrive
, необходимо применять методы GetAbsolutePathName
и GetDriveName
:
DriveSpec = GetDriveName(GetAbsolutePathName(Path))
Для иллюстрации работы этого метода запустим сценарий ParentFolder.js (листинг 5.4). В результате будет выведено диалоговое окно с полным путем к файлу и путь к родительскому каталогу этого файла (рис. 5.2).
Рис. 5.2. Полный путь к файлу и родительский каталог этого файла
/*******************************************************************/
/* Имя: ParentFolder.js */
/* Язык: JScript */
/* Описание: Определение родительского каталога для файла */
/*******************************************************************/
var FSO,ParentFolder,Spath,s; //Объявляем переменные
//Создаем объект FileSystemObject
FSO = WScript.CreateObject("Scripting.FileSystemObject");
//Задаем путь к файлу
SPath="C:\\Programs\\letter.txt";
//Определяем родительский каталог для файла letter.txt
ParentFolder = FSO.GetParentFolderName(SPath);
s="Путь: "+SPath+"\n";
s+="Родительский каталог: "+ParentFolder;
//Выводим на экран полный путь к файлу letter.txt
//и родительский каталог для этого файла
WScript.Echo(s);
/************* Конец *********************************************/
Параметр
в этом методе является числом и может принимать значения, описанные в табл. 5.4.folderspec
Таблица 5.4. Значения параметра folderspec
Константа | Значение | Описание |
---|---|---|
|
0 | Каталог Windows (например, " ") |
|
1 | Системный каталог, содержащий файлы библиотек, шрифтов и драйверы устройств |
|
2 | Каталог для временных файлов, путь к которому хранится в переменной среды |
Метод
GetTempName
только возвращает имя файла, но не создает его. Для создания файла можно воспользоваться методом CreateTextFile
, подставив в качестве параметра этого метода сгенерированное случайное имя (листинг 5.5).
/*******************************************************************/
/* Имя: TempFile.js */
/* Язык: JScript */
/* Описание: Создание временного файла со случайным именем */
/*******************************************************************/
var FSO,FileName,f,s; //Объявляем переменные
//Создаем объект FileSystemObject
FSO = WScript.CreateObject("Scripting.FileSystemObject");
//Генерируем случайное имя файла
FileName=FSO.GetTempName();
//Создаем файл и именем FileName
f = FSO.CreateTextFile(FileName, true);
//Закрываем файл
f.Close();
//Сообщаем о создании файла
WScript.Echo("Был создан файл",FileName);
/************* Конец *********************************************/
Как и при использовании методов
CopyFile
и CopyFolder
, для перемещения нескольких файлов или каталогов в последнем компоненте параметра source
можно указывать групповые символы (? и *); в параметре destination
групповые символы недопустимы.
При использовании методов
MoveFile
и MoveFolder
процесс перемещения прерывается после первой возникшей ошибки (как и в команде move операционной системы). Перемещать файлы и каталоги с одного диска на другой нельзя.
Числовой параметр
задает режим ввода/вывода для открываемого файла и может принимать следующие значения (табл. 5.5).iomode
Таблица 5.5. Параметр iomode
Константа | Значение | Описание |
---|---|---|
|
1 | Файл открывается только для чтения, записывать информацию в него нельзя |
|
2 | Файл открывается для записи. Если файл с таким именем уже существовал, то при новой записи его содержимое теряется |
|
8 | Файл открывается для добавления. Если файл уже существовал, то информация будет дописываться в конец этого файла |
Параметр
имеет значение в том случае, когда открываемый файл физически не существует. Если create
равно create
true
, то этот файл создастся, если же в качестве значения create указано false
или параметр create
опущен, то файл создаваться не будет.
Числовой параметр
определяет формат открываемого файла (табл. 5.6).format
Таблица 5.6. Параметр format
Константа | Значение | Описание |
---|---|---|
|
-2 | Файл открывается в формате, используемом системой по умолчанию |
|
-1 | Файл открывается в формате Unicode |
|
0 | Файл открывается в формате ASCII |
Для дальнейшей работы с открытым файлом, т.е. для записи или чтения информации, нужно использовать методы объекта
TextStream
.
В следующем примере с помощью метода
OpenTextFile
текстовый файл открывается в режиме добавления информации (листинг 5.6).
/*******************************************************************/
/* Имя: AppendFile.js */
/* Язык: JScript */
/* Описание: Добавление строки в текстовый файл */
/*******************************************************************/
//Объявляем переменные и инициализируем константы
var FSO,f,ForAppending = 8;
//Создаем объект FileSystemObject
FSO = WScript.CreateObject("Scripting.FileSystemObject");
//Открываем файл
f = FSO.OpenTextFile("C:\\TestFile.txt", ForAppending, true);
//Добавление в файл строку
f.WriteLine("Привет!");
//Закрываем файл
f.Close();
/************* Конец *********************************************/
Мнемонические константы, используемые в качестве параметров
и iomode
, можно не определять явным образом в сценарии, как это сделано в вышеприведенном примере, а брать из самого объекта create
FileSystemObject
(точнее говоря, из библиотеки типов этого объекта). Для этого в сценариях нужно применять разметку XML (см. листинг 3.9).
С помощью объекта
Drive
можно получить доступ к свойствам заданного локального или сетевого диска. Создается объект Drive
с помощью метода GetDrive
объекта FileSystemObject
следующим образом:
var FSO, D;
FSO = WScript.CreateObject("Scripting.FileSystemObject");
D = FSO.GetDrive("C:");
Также объекты
Drive
могут быть получены как элементы коллекции Drives
.
Свойства объекта
Drive
представлены в табл. 5.7; методов у этого объекта нет.
Таблица 5.7. Свойства объекта Drive
Свойство | Описание |
---|---|
|
Содержит количество доступного для пользователя места (в байтах) на диске |
|
Содержит букву, ассоциированную с локальным устройством или сетевым ресурсом. Это свойство доступно только для чтения |
|
Содержит числовое значение, определяющее тип устройства: 0 — неизвестное устройство; 1 — устройство со сменным носителем; 2 — жесткий диск; 3 — сетевой диск; 4 — CD-ROM; 5 — RAM-диск |
|
Содержит тип файловой системы, использующейся на диске (FAT, NTFS или CDFS) |
|
Содержит количество свободного места (в байтах) на локальном диске или сетевом ресурсе. Доступно только для чтения |
|
Содержит , если устройство готово, и в противном случае. Для устройств со сменными носителями и приводов CD-ROM возвращает только в том случае, когда в дисковод вставлен соответствующий носитель и устройство готово предоставить доступ к этому носителю |
|
Содержит путь к диску (например, " ", но не " ") |
|
Содержит объект , соответствующий корневому каталогу на диске. Доступно только для чтения |
|
Содержат десятичный серийный номер тома заданного диска |
|
Содержит сетевое имя для диска. Если объект не является сетевым диском, то в свойстве содержится пустая строка ("") |
|
Содержит общий объем в байтах локального диска или сетевого ресурса |
|
Содержит метку тома для диска. Доступно для чтения и записи |
В листинге 5.7 приведен сценарий DriveInfo.js, в котором объект
Drive
используется для доступа к некоторым свойствам диска С: (рис. 5.3).
Рис. 5.3. Свойства диска С:
/*******************************************************************/
/* Имя: DriveInfo.js */
/* Язык: JScript */
/* Описание: Вывод на экран свойств диска C: */
/*******************************************************************/
//Объявляем переменные
var FSO,D,TotalSize,FreeSpace,s;
//Создаем объект FileSystemObject
FSO = WScript.CreateObject("Scripting.FileSystemObject");
//Создаем объект Drive для диска C:
D = FSO.GetDrive("C:");
s="Информация о диске C:\n";
//Получаем серийный номер диска
s+="Серийный номер: "+D.SerialNumber+"\n";
//Получаем метку тома диска
s+="Метка тома: "+D.VolumeName+"\n";
//Вычисляем общий объем диска в килобайтах
TotalSize=D.TotalSize/1024;
s+="Объем: "+TotalSize+" Kb\n";
//Вычисляем объем свободного пространства диска в килобайтах
FreeSpace=D.FreeSpace/1024;
s+="Свободно: "+FreeSpace+" Kb\n";
//Выводим свойства диска на экран
WScript.Echo(s);
/************* Конец *********************************************/
Доступная только для чтения коллекция
Drives
содержит объекты Drive
для всех доступных дисков компьютера, в том числе для сетевых дисков и дисководов со сменными носителями.
В свойстве
Count
коллекции Drives
хранится число ее элементов, т.е. число доступных дисков.
С помощью метода
Item(drivespec)
можно получить доступ к объекту Drive
для диска, заданного параметром drivespec
. Например:
var FSO, DriveCol, D; //Создаем объект FileSystemObject
FSO = WScript.CreateObject("Scripting.FileSystemObject");
//Создаем коллекцию имеющихся в системе дисков
DriveCol = FSO.Drives;
// Извлечение элемента коллекции (диск С:)
D = DriveCol.Item("С:");
//Вывод на экран метки тома диска С:
WScript.Echo("Диск С: имеет метку", D.VolumeName);
Для перебора всех элементов коллекции
Drives
нужно, как обычно, использовать объект Enumerator
.
В листинге 5.8 приведен файл ListDrives.js, в котором с помощью объекта
Enumerator
на экран выводятся сведения обо всех доступных дисках (рис. 5.4).
Рис. 5.4. Список всех дисков, имеющихся в системе
/*******************************************************************/
/* Имя: ListDrives.js */
/* Язык: JScript */
/* Описание: Получение списка всех имеющихся дисков */
/*******************************************************************/
//Объявляем переменные
var FSO,s,ss,Drives,D;
//Создаем объект FileSystemObject
FSO = WScript.CreateObject("Scripting.FileSystemObject");
//Создаем коллекцию дисков, имеющихся в системе
Drives = new Enumerator(FSO.Drives);
s="";
//Цикл по всем дискам в коллекции
for (;!Drives.atEnd();Drives.moveNext()) {
//Извлекаем текущий элемента коллекции
D=Drives.item();
//Получаем букву диска
s+=D.DriveLetter;
s+=" - ";
if (D.DriveType == 3) //Проверяем, не является ли диск сетевым
//Получаем имя сетевого ресурса
ss=D.ShareName;
else
//Диск является локальным
if (D.IsReady) //Проверяем готовность диска
//Если диск готов, то получаем метку тома для диска
ss=D.VolumeName;
else ss="Устройство не готово";
s+=ss+"\n";
}
//Выводим полученные строки на экран
WScript.Echo(s);
/************* Конец *********************************************/
Объект
Folder
обеспечивает доступ к свойствам каталога. Создать этот объект можно с помощью свойства RootFolder
объекта Drive
или методов GetFolder
, GetParentFolder
и GetSpecialFolder
объекта FileSystemObject
следующим образом:
var FSO, Folder;
FSO = WScript.CreateObject("Scripting.FileSystemObject");
Folder = FSO.GetFolder("С:\\Мои документы");
Также объекты
Folder
могут быть получены как элементы коллекции Folders
.
Свойства объекта
Folder
представлены в табл. 5.8.
Таблица 5.8. Свойства объекта Folder
Свойство | Описание |
---|---|
|
Позволяет просмотреть или установить атрибуты каталога |
|
Содержит дату и время создания каталога. Доступно только для чтения |
|
Содержит дату и время последнего доступа к каталогу. Доступно только для чтения |
|
Содержит дату и время последней модификации каталога. Доступно только для чтения |
|
Содержит букву диска для устройства, на котором находится каталог. Доступно только для чтения |
|
Содержит коллекцию , состоящую из объектов для всех файлов в каталоге (включая скрытые и системные) |
|
Содержит , если каталог является корневым, и в противном случае |
|
Позволяет просмотреть и изменить имя каталога. Доступно для чтения и записи |
|
Содержит объект для родительского каталога. Доступно только для чтения |
|
Содержит путь к каталогу |
|
Содержит короткое имя каталога (в формате 8.3) |
|
Содержит путь к каталогу, состоящий из коротких имен каталогов (в формате 8.3) |
|
Содержит размер всех файлов и подкаталогов, входящих в данный каталог, в байтах |
|
Содержит коллекцию , состоящую из всех подкаталогов каталога (включая подкаталоги с атрибутами "Скрытый" и "Системный") |
|
Содержит информацию о типе каталога |
Следующий пример показывает, как объект
Folder
используется для получения даты создания каталога (листинг 5.9).
/*******************************************************************/
/* Имя: DateFolder.js */
/* Язык: JScript */
/* Описание: Вывод на экран даты создания текущего каталога */
/*******************************************************************/
var FSO,WshShell,s; //Объявляем переменные
//Создаем объект FileSystemObject
FSO = WScript.CreateObject("Scripting.FileSystemObject");
//Создаем объект WshShell
WshShell=WScript.CreateObject("WScript.Shell");
//Определяем каталог, из которого был запущен сценарий
//(текущий каталог)
Folder = FSO.GetFolder(WshShell.CurrentDirectory);
//Получаем имя текущего каталога
s="Текущий каталог: "+Folder.Name+"\n";
//Получаем дату создания текущего каталога
s+="Дата создания: "+Folder.DateCreated+"\n";
//Выводим информацию на экран
WScript.Echo(s);
/************* Конец *********************************************/
Методы объекта
Folder
описаны в табл. 5.9.
Таблица 5.9. Методы объекта Folder
Метод | Описание |
---|---|
|
Копирует каталог в другое место |
|
Создает новый текстовый файл с именем и возвращает указывающий на этот файл объект (этот метод аналогичен рассмотренному выше методу объекта ) |
|
Удаляет каталог |
Move(destination) | Перемещает каталог в другое место |
Приведем необходимые замечания для методов из табл. 5.9.
Обязательный параметр
определяет каталог, в который будет производиться копирование; групповые символы в имени каталога недопустимы.destination
Параметр
является логической переменной, определяющей, следует ли заменять уже существующий каталог с именем overwrite
(destination
overwrite=true
) или нет (overwrite=false
).
Вместо метода
Сору
можно использовать метод CopyFolder
объекта FileSystemObject
.
Если параметр
равен force
false
или не указан, то с помощью метода Delete
будет нельзя удалить каталог с атрибутом "только для чтения" (read-only). Установка для force значения true позволит сразу удалять такие каталоги.
При использовании метода
Delete
неважно, является ли заданный каталог пустым или нет — он удалится в любом случае.
Вместо метода
Delete
можно использовать метод DeleteFolder
объекта FileSystemObject
.
Обязательный параметр
определяет каталог, в который будет производиться перемещение; групповые символы в имени каталога недопустимы.destination
Вместо метода
Move
можно использовать метод MoveFolder
объекта FileSystemObject
.
Коллекция
Folders
содержит объекты Folder
для всех подкаталогов определенного каталога. Создается эта коллекция с помощью свойства SubFolders
соответствующего объекта Folder
. Например, в следующем примере переменная SubFolders
является коллекцией, содержащей объекты Folder
для всех подкаталогов каталога C:\Program Files:
var FSO, F, SubFolders;
//Создаем объект FileSystemObject
FSO=WScript.CreateObject("Scripting.FileSystemObject");
//Создаем объект Folder для каталога C:\Program Files
F=FSO.GetFolder("C:\\Program Files");
//Создаем коллекцию подкаталогов каталога C:\Program Files
SubFolders=F.SubFolders;
Коллекция
Folders
(как и Drives
) имеет свойство Count
и метод Item
. Кроме этого, у Folders
есть метод Add(folderName)
, позволяющий создавать новые подкаталоги. В листинге 5.10 приведен сценарий MakeSubFold.js, который создает в каталоге "С:\Мои документы" подкаталог "Новая папка".
/*******************************************************************/
/* Имя: MakeSubFold.js */
/* Язык: JScript */
/* Описание: Создание нового каталога */
/*******************************************************************/
//Объявляем переменные
var FSO, F, SubFolders;
//Создаем объект FileSystemObject
FSO=WScript.CreateObject("Scripting.FileSystemObject");
//Создаем объект Folder для каталога C:\Program Files
F=FSO.GetFolder("C:\\Program Files");
//Создаем коллекцию подкаталогов каталога C:\Program Files
SubFolders=F.SubFolders;
// Создаем каталог C:\Program Files\Новая папка
SubFolders.Add("Новая папка");
/************* Конец *********************************************/
Напомним, что новый каталог также можно создать с помощью метода
CreateFolder
объекта FileSystemObject
.
Для доступа ко всем элементам коллекции нужно использовать, как обычно, объект
Enumerator
. Например, в листинге 5.11 приведен сценарий ListSubFold.js, в котором на экран выводятся названия всех подкаталогов каталога C:\Program Files (рис. 5.5).
Рис. 5.5. Список всех подкаталогов каталога C:\Program Files
/*******************************************************************/
/* Имя: ListSubFold.js */
/* Язык: JScript */
/* Описание: Получение списка всех подкаталогов заданного каталога */
/*******************************************************************/
//Объявляем переменные
var FSO,F,SFold,SubFolders,s;
//Создаем объект FileSystemObject
FSO=WScript.CreateObject("Scripting.FileSystemObject");
//Путь к каталогу
SFold="C:\\Program Files";
s="Каталог "+SFold+"\n";
s+="Подкаталоги:\n";
//Создаем объект Folder для каталога C:\Program Files
F=FSO.GetFolder(SFold);
//Создаем коллекцию подкаталогов каталога C:\Program Files
SubFolders= new Enumerator(F.SubFolders);
//Цикл по всем подкаталогам
for (; !SubFolders.atEnd(); SubFolders.moveNext()) {
s+=SubFolders.item()+"\n"; //Добавляем строку с именем подкаталога
}
//Выводим полученные строки на экран
WScript.Echo(s);
/************* Конец *********************************************/
Объект
File
обеспечивает доступ ко всем свойствам файла. Создать этот объект можно с помощью метода GetFile
объекта FileSystemObject
следующим образом:
var FSO, F;
//Создаем объект FileSystemObject
FSO=WScript.CreateObject("Scripting.FileSystemObject");
//Создаем объект File
F=FSO.GetFile("С:\\Мои документах\letter.txt");
Также объекты
File
могут быть получены как элементы коллекции Files
. Свойства объекта File
описаны в табл. 5.10.
Таблица 5.10. Свойства объекта File
Свойство | Описание |
---|---|
|
Позволяет просмотреть или установить атрибуты файлов |
|
Содержит дату и время создания файла. Доступно только для чтения |
|
Содержит дату и время последнего доступа к файлу. Доступно только для чтения |
|
Содержит дату и время последней модификации файла. Доступно только для чтения |
|
Содержит букву диска для устройства, на котором находится файл. Доступно только для чтения |
|
Позволяет просмотреть и изменить имя файла. Доступно для чтения и записи |
|
Содержит объект для родительского каталога файла. Доступно только для чтения |
|
Содержит путь к файлу |
|
Содержит короткое имя файла (в формате 8.3) |
|
Содержит путь к файлу, состоящий из коротких имен каталогов (в формате 8.3) |
|
Содержит размер заданного файла в байтах |
|
Возвращает информацию о типе файла. Например, для файла с расширением txt возвратится строка " " |
Методы объекта
File
представлены в табл. 5.11.
Таблица 5.11. Методы объекта File
Метод | Описание |
---|---|
|
Копирует файл в другое место |
|
Удаляет файл |
|
Перемещает файл в другое место |
|
Открывает заданный файл и возвращает объект , который может быть использован для чтения, записи или добавления данных в текстовый файл |
Приведем необходимые замечания для методов из табл. 5.11.
Обязательный параметр
определяет файл, в который будет производиться копирование; групповые символы в имени файла недопустимы.destination
Параметр
является логической переменной, определяющей, следует ли заменять уже существующий файл с именем overwrite
(destination
overwrite=true
) или нет (overwrite=false
).
В листинге 5.12 приведен сценарий CopyFile.js, иллюстрирующий использование метода Сору. В этом сценарии на диске С: создается файл TestFile.txt, который затем копируется на рабочий стол.
/*******************************************************************/
/* Имя: CopyFile.js */
/* Язык: JScript */
/* Описание: Создание и копирование файла */
/*******************************************************************/
//Объявляем переменные
var FSO,F,WshShell,WshFldrs,PathCopy;
//Создаем объект FileSystemObject
FSO=WScript.CreateObject("Scripting.FileSystemObject");
//Создаем файл
F=FSO.CreateTextFile("C:\\TestFile.txt", true);
//Записываем в файл строку
F.WriteLine("Тестовый файл");
//Закрываем файл
F.Close();
//Создаем объект WshShell
WshShell=WScript.CreateObject("Wscript.Shell");
//Создаем объект WshSpecialFolders
WshFldrs=WshShell.SpecialFolders;
//Определяем путь к рабочему столу
PathCopy=WshFldrs.item("Desktop")+"\\";
//Создаем объект File для файла C:\TestFile.txt
F=FSO.GetFile("C:\\TestFile.txt");
//Копируем файл на рабочий стол
F.Copy(PathCopy);
/************* Конец *********************************************/
Вместо метода
Сору
можно использовать метод CopyFile
объекта FileSystemObject
.
Если параметр
равен force
false
или не указан, то с помощью метода Delete
будет нельзя удалить файл с атрибутом "только для чтения" (read-only). Установка для force
значения true
позволит сразу удалять такие файлы.
Вместо метода
Delete
можно использовать метод DeleteFile
объекта FileSystemObject
.
Обязательный параметр
определяет файл, в который будет производиться перемещение; групповые символы в имени файла недопустимы.destination
Вместо метода
Move
можно использовать метод MoveFile
объекта FileSystemObject
.
Числовой параметр
задает режим ввода/вывода для открываемого файла и может принимать те же значения, что и одноименный параметр в методе iomode
OpenTextFile
объекта FileSystemObject
(табл. 5.5).
Числовой параметр
определяет формат открываемого файла (ASCII или Unicode). Этот параметр также может принимать те же значения, что и format
в методе format
OpenTextFile
объекта FileSystemObject
(табл. 5.6).
Открыть текстовый файл для чтения можно также с помощью метода
OpenTextFile
объекта FileSystemObject
.
В листинге 5.13 приведен сценарий WriteTextFile.js, иллюстрирующий использование метода OpenAsTextStream для записи строки в файл и чтения из него.
/*******************************************************************/
/* Имя: WriteTextFile.js */
/* Язык: JScript */
/* Описание: Запись строк в текстовый файл и чтение из него */
/*******************************************************************/
var FSO,F,TextStream,s; //Объявляем переменные
//Инициализируем константы
var ForReading = 1, ForWriting = 2, TristateUseDefault = -2;
//Создаем объект FileSystemObject
FSO=WScript.CreateObject("Scripting.FileSystemObject");
//Создаем в текущем каталоге файл test1.txt
FSO.CreateTextFile("test1.txt");
//Создаем объект File для файла test1.txt
F=FSO.GetFile("test1.txt");
//Создаем объект TextStream (файл открывается для записи)
TextStream=F.OpenAsTextStream(ForWriting, TristateUseDefault);
//Записываем в файл строку
TextStream.WriteLine("Это первая строка");
//Закрываем файл
TextStream.Close();
//Открываем файл для чтения
TextStream=F.OpenAsTextStream(ForReading, TristateUseDefault);
//Считываем строку из файла
s=TextStream.ReadLine();
//Закрываем файл
TextStream.Close();
//Отображаем строку на экране
WScript.Echo("Первая строка из файла test1.txt:\n\n",s);
/************* Конец *********************************************/
Коллекция
Files
содержит объекты File
для всех файлов, находящихся внутри определенного каталога. Создается эта коллекция с помощью свойства Files
соответствующего объекта Folder
. Например, в следующем примере переменная Files
является коллекцией, содержащей объекты File
для всех файлов в каталоге С:\Мои документы:
var FSO, F, Files;
FSO=WScript.CreateObject("Scripting.FileSystemObject");
F=FSO.GetFolder("С:\\Мои документы");
Files=F.Files;
Как и рассмотренные выше коллекции
Drives
и Folders
, коллекция Files
имеет свойство Count
и метод Item
.
Для доступа в цикле ко всем элементам коллекции
Files
применяется объект Enumerator
. В качестве примера использования этого объекта в листинге 5.14 приведен сценарий ListFiles.js, выводящий на экран названия всех файлов, которые содержатся в специальной папке "Мои документы" (рис. 5.6).
Рис. 5.6. Список всех файлов в специальной папке "Мои документы"
/*******************************************************************/
/* Имя: ListFiles.js */
/* Язык: JScript */
/* Описание: Получение списка всех файлов заданного каталога */
/*******************************************************************/
//Объявляем переменные
var FSO,F,Files,WshShell,PathList,s;
//Создаем объект FileSystemObject
FSO=WScript.CreateObject("Scripting.FileSystemObject");
//Создаем объект WshShell
WshShell=WScript.CreateObject("Wscript.Shell");
//Создаем объект WshSpecialFolders
WshFldrs=WshShell.SpecialFolders;
//Определяем путь к папке "Мои документы"
PathList=WshFldrs.item("MyDocuments")+"\\";
//Создаем объект Folder для папки "Мои документы"
F=FSO.GetFolder(PathList);
//Создаем коллекцию файлов каталога "Мои документы"
Files=new Enumerator(F.Files);
s = "Файлы из каталога "+PathList+"\n";
//Цикл по всем файлам
for (; !Files.atEnd(); Files.moveNext())
//Добавляем строку с именем файла
s+=Files.item().Name+"\n";
//Выводим полученные строки на экран
WScript.Echo(s);
/************* Конец *********************************************/
Объект
TextStream
обеспечивает последовательный (строка за строкой) доступ к текстовому файлу. Методы этого объекта позволяют читать информацию из файла и записывать ее в него.
Создать объект
TextStream
можно с помощью следующих методов:
□
CreateTextFile
объектов FileSystemObject
и Folder
;
□
OpenTextFile
объекта FileSystemObject
;
□
OpenAsTextStream
объекта File
.
В следующем примере переменная
F
является объектом TextStream и используется для записи строки текста в файл C:\TestFile.txt:
//Создаем объект FileSystemObject
var FSOWScript.CreateObject("Scripting. FileSystemObject");
//Создаем текстовый файл
var F=FSO.CreateTextFile("C:\\TestFile.txt", true);
//Записываем строку в файл
F.WriteLine("Строка текста");
//Закрываем файл
F.Close();
Свойству объекта TextStream описаны в табл. 5.12.
Таблица 5.12. Свойства объекта TextStream
Свойство | Описание |
---|---|
|
Содержит , если указатель достиг конца строки в файле, и в противном случае. Доступно только для чтения |
|
Содержит , если указатель достиг конца файла, и в противном случае. Доступно только для чтения |
|
Содержит номер колонки текущего символа в текстовом файле. Доступно только для чтения |
|
Содержит номер текущей строки в текстовом файле. Доступно только для чтения |
Методы объекта
TextStream
представлены в табл. 5.13.
Таблица 5.13. Методы объекта TextStream
Метод | Описание |
---|---|
|
Закрывает открытый файл |
|
Считывает из файла символов и возвращает полученную строку |
|
Считывает полностью весь файл и возвращает полученную строку |
|
Возвращает полностью считанную из файла строку |
|
Пропускает при чтении символов |
|
Пропускает целую строку при чтении |
|
Записывает в файл строку (без символа конца строки) |
|
Записывает в файл пустых строк (символы перевода строки и возврата каретки) |
|
Записывает в файл строку (вместе с символом конца строки). Если параметр опущен, то в файл записывается пустая строка |
В листинге 5.15 приведен сценарий TextFile.js, иллюстрирующий использование методов объекта
TextStream
. В этом сценарии на диске С: создается файл TestFile.txt и в него записываются три строки, вторая из которых является пустой. После этого файл открывается для чтения и из него считывается третья строка, которая выводится на экран (рис. 5.7).
Рис. 5.7. Результат работы сценария TextFile.js
/*******************************************************************/
/* Имя: TextFile.js */
/* Язык: JScript */
/* Описание: Работа с текстовым файлом (запись и чтение информации)*/
/*******************************************************************/
var FSO,F,s; //Объявляем переменные
var ForReading = 1; //Инициализируем константы
//Создаем объект FileSystemObject
FSO=WScript.CreateObject("Scripting.FileSystemObject");
//Создаем на диске C: текстовый файл TestFile.txt
F=FSO.CreateTextFile("C:\\TestFile.txt", true);
//Записываем в файл первую строку
F.Write("Это ");
F.WriteLine("первая строка");
//Записываем в файл пустую строку
F.WriteBlankLines(1);
//Записываем в файл третью строку
F.WriteLine("Это третья строка");
//Закрываем файл
F.Close();
//Открываем файл для чтения
F=FSO.OpenTextFile("C:\\TestFile.txt", ForReading);
//Пропускаем в файле две первые строки
F.SkipLine();
F.SkipLine();
s="Третья строка из файла C:\\TestFile.txt:\n";
//Считываем из файла третью строку
s+=F.ReadLine();
//Выводим информацию на экран
WScript.Echo(s);
/************* Конец *********************************************/
Ниже подробно рассмотрены несколько завершенных сценариев, иллюстрирующих работу с файловой системой компьютера.
Напишем сценарий DrivesReport.js, который будет создавать таблицу использования дискового пространства для дисков всех типов (съемных, жестких и сетевых), имеющихся на компьютере, в следующем формате:
Диск: буква_диска | |
Метка тома: метка | Общий объем, Mb: n1 |
Используется, Mb: n2 | Свободно, Mb: n3 |
Для этого в сценарии вывод информации производится в текстовый файл rep.txt (переменная
RepFile
), который затем открывается с помощью Блокнота (рис. 5.8):
//Создаем объект WshShell
WshShell=WScript.CreateObject("WScript.Shell");
//Запускаем Блокнот (notepad.exe) и открываем в нем файл rep.txt
WshShell.Run("notepad.exe rep.txt");
Данные об одном диске формируются в функции
WriteDriveInfo(drive)
, где в качестве параметра drive
подставляется объект Dr
ive для нужного диска. Соответствующие объекты Drive
для всех дисков, имеющихся в системе, создаются в функции LoopDrives()
:
// Функция для перебора в цикле всех устройств (дисков)
function LoopDrives() {
var Drives;
//Создаем коллекцию дисков
Drives = new Enumerator( FSO.Drives );
//Цикл по всем дискам
for(; !Drives.atEnd(); Drives.moveNext()) WriteDriveInfo(Drives.item());
}
Рис. 5.8. Сформированный отчет об использовании дискового пространства
В функции
WriteDriveInfo(drive)
сначала проверяется готовность устройства drive
— если свойство IsReady
объекта Drive
равно true
, то для этого устройства определяются общий объем (свойство TotalSize
), объем свободного пространства (свойство FreeSpace
), буква диска (свойство DriveLetter
) и метка тома (свойство FreeSpace
):
//Вычисляем общий объем диска в мегабайтах
Total = Math.round(drive.TotalSize/1048576);
//Вычисляем объем свободного пространства в мегабайтах
Free = Math.round(drive.FreeSpace/1048576);
//Вычисляем объем использованного пространства в мегабайтах
Used = Total - Free;
//Определяем букву диска
DriveLetter=drive.DriveLetter+":";
//Определяем метку тома
VolumeName=drive.VolumeName;
Строки с полученными значениями затем приводятся к нужному виду с помощью вспомогательных функций
LFillStr
(выравнивание строки влево), FillStr
(выравнивание строки по центру) и записываются в выходной файл RepFile
:
RepFile.WriteLine("+---------------------------------------------------+");
//Записываем информацию о букве диска
s="|"+FillStr(51,"Диск "+DriveLetter)+"|";
RepFile.WriteLine(s);
RepFile.WriteLine("+---------------------------------------------------+");
//Записываем информацию о метке тома
s="|"+LFillStr(25,"Метка тома: "+VolumeName)+"|";
//Записываем информацию об общем объеме диска
s+=LFillStr(25,"Общий объем, Mb: "+Total)+"|";
RepFile.WriteLine(s);
RepFile.WriteLine("+---------------------------------------------------+");
//Записываем информацию об использованном пространстве
s="|"+LFillStr(25,"Используется, Mb: "+Used.toString())+"|";
//Записываем информацию о свободном пространстве
s+=LFillStr(25,"Свободно, Mb: "+Free.toString())+"|";
RepFile.WriteLine(s);
RepFile.WriteLine("+---------------------------------------------------+");
Если же устройство
не готово (свойство drive
IsReady
равно false
), то с помощью свойства DriveType
проверяется, не является ли ли диск сетевым (в этом случае DriveType=3
), после чего в файл выводится соответствующее сообщение:
if (drive.DriveType == 3) { //Проверяем, является ли диск сетевым
//Записываем информацию о букве диска
RepFile.WriteLine( "Диск " + drive.DriveLetter + " является сетевым" );
//Записываем пустые строки
RepFile.WriteLine();
RepFile.WriteLine();
} else {
//Устройство не готово
RepFile.WriteLine( "Устройство " + drive.DriveLetter + ": не готово" );
//Записываем пустые строки
RepFile.WriteLine();
RepFile.WriteLine();
}
Полный текст сценария DrivesReport.js приведен в листинге 5.16.
/*******************************************************************/
/* Имя: DrivesReport.js */
/* Язык: JScript */
/* Описание: Формирование отчета об использовании дискового */
/* пространства для всех устройств на компьютере */
/*******************************************************************/
//Объявляем переменные
var FSO, RepFile, MDate,WshShell, ForWriting = 2;
// Функция для перебора в цикле всех устройств (дисков)
function LoopDrives() {
var Drives;
//Создаем коллекцию дисков
Drives = new Enumerator( FSO.Drives );
//Цикл по всем дискам
for(; !Drives.atEnd(); Drives.moveNext()) WriteDriveInfo(Drives.item());
}
// Функция для вывода информации об одном устройстве (диске)
function WriteDriveInfo(drive) {
var s,Total,Free,Used,DriveLetter,VolumeName;
if (drive.IsReady) { //Проверяем готовность устройства
//Вычисляем общий объем диска в мегабайтах
Total = Math.round(drive.TotalSize/1048576);
//Вычисляем объем свободного пространства в мегабайтах
Free = Math.round(drive.FreeSpace/1048576);
//Вычисляем объем использованного пространства в мегабайтах
Used = Total - Free;
//Определяем букву диска
DriveLetter=drive.DriveLetter+":";
//Определяем метку тома
VolumeName=drive.VolumeName;
RepFile.WriteLine("+---------------------------------------------------+");
//Записываем информацию о букве диска
s="|"+FillStr(51,"Диск "+DriveLetter)+"|";
RepFile.WriteLine(s);
RepFile.WriteLine("+---------------------------------------------------+");
//Записываем информацию о метке тома
s="|"+LFillStr(25,"Метка тома: "+VolumeName)+"|";
//Записываем информацию об общем объеме диска
s+=LFillStr(25,"Общий объем, Mb: "+Total)+"|";
RepFile.WriteLine(s);
RepFile.WriteLine("+---------------------------------------------------+");
//Записываем информацию об использованном пространстве
s="|"+LFillStr(25,"Используется, Mb: "+Used.toString())+"|";
//Записываем информацию о свободном пространстве
s+=LFillStr(25,"Свободно, Mb: "+Free.toString())+"|";
RepFile.WriteLine(s);
RepFile.WriteLine("+---------------------------------------------------+");
//Записываем пустые строки
RepFile.WriteLine();
RepFile.WriteLine();
} else if (drive.DriveType == 3) { //Проверяем, является ли диск сетевым
//Записываем информацию о букве диска
RepFile.WriteLine( "Диск " + drive.DriveLetter + " является сетевым" );
//Записываем пустые строки
RepFile.WriteLine();
RepFile.WriteLine();
} else {
//Устройство не готово
RepFile.WriteLine( "Устройство " + drive.DriveLetter + ": не готово" );
//Записываем пустые строки
RepFile.WriteLine();
RepFile.WriteLine();
}
}
/******************* Начало **********************************/
//Создаем объект FileSystemObject
FSO = WScript.CreateObject("Scripting.FileSystemObject");
//Открываем файл rep.txt
RepFile = FSO.OpenTextFile("rep.txt", ForWriting, true);
//Определяем текущую дату и время
MDate = new Date();
//Записываем дату и время в отчет
RepFile.WriteLine("Дата отчета: " + MDate);
RepFile.WriteLine();
//Вызываем функцию LoopDrives
LoopDrives();
//Закрываем файл rep.txt
RepFile.Close();
//Создаем объект WshShell
WshShell=WScript.CreateObject("WScript.Shell");
//Запускаем Блокнот (notepad.exe) и открываем в нем файл rep.txt
WshShell.Run("notepad.exe rep.txt");
/************* Конец *********************************************/
// Вспомогательные функции
//Выравнивание строки s вправо в поле длиной l символов
function RFillStr(l,s) {
var ss,i,ll;
ll=l-s.length;
if (s.length>=l) {
return(s);
} else {
ss=s;
for (i=1;i<=ll;i++) {
ss=" "+ss;
}
return(ss);
}
}
//Выравнивание строки s влево в поле длиной l символов
function LFillStr(l,s) {
var ss,i,ll;
ll=l-s.length;
if (s.length>=l) {
return(s);
} else {
ss=s;
for (i=1;i<=ll;i++) {
ss=ss+" ";
}
return(ss);
}
}
//Выравнивание строки s по центру в поле длиной l символов
function FillStr(l,s) {
var ss,i,ll,s1,l2;
ll=l-s.length;
if (s.length>=l) {
return(s);
} else {
ss=s;
l2=Math.round((l-s.length)/2);
ss=LFillStr(s.length+l2,s);
ss=RFillStr(l,ss);
return(ss);
}
}
В результате некорректного завершения приложений на жестком диске часто остаются "бесхозные" временные файлы (с расширением tmp), которые затем приходится удалять вручную. Весьма удобно было бы удалять все такие файлы сразу со всего жесткого диска, не заботясь о том, в каких каталогах они находятся. Используя стандартные средства операционной системы, можно сначала с помощью пункта Найти (Find) меню Пуск (Start) составить список всех временных файлов (рис. 5.9), затем выделить все файлы в этом списке и нажать комбинацию клавиш
Однако если хотя бы один из временных файлов будет занят каким-либо приложением, то в доступе к нему будет отказано и процесс удаления прервется (рис. 5.10).
Поэтому для удаления с жесткого диска всех временных файлов мы напишем сценарий DelTmp.js (основная идея, которая используется в данном сценарии, позаимствована из статьи [6]).
Алгоритм работы сценария состоит в следующем:
□ в Блокноте (notepad.exe) создается новый файл для отображения в нем результатов работы;
□ на диске D: просматриваются подкаталоги всех уровней вложенности;
□ в каждом подкаталоге ищутся все временные файлы с расширением tmp;
□ для каждого найденного временного файла производится попытка удаления. В случае успеха в Блокноте печатается путь к файлу и слово "OK", если же удаляемый файл занят, то печатается путь к файлу и слово "Busy" ("Занят");
□ после просмотра всех каталогов в Блокноте печатается общее количество найденных временных файлов (рис. 5.11).
Рис. 5.9. Список всех временных файлов на диске D:
Рис. 5.10. Ошибка, возникающая при попытке удалить занятый файл
Итак, наиболее важными в сценарии являются: функция
DelFilesInFolder(Fold, SExt)
, в которой происходит попытка удаления в каталоге Fold всех файлов, имеющих расширение SExt
, и рекурсивная (т.е. содержащая обращение к самой себе) функция LoopSubFolders(Fold)
, в которой происходит вызов функции DelFilesInFolder
для подкаталогов каталога Fold.
Рис. 5.11. Результат работы сценария DelTmp.js
Рассмотрим сначала функцию
DelFilesInFolder(Fold, SExt)
. Здесь сначала создается объект Enumerator
с именем Files
для доступа к коллекции всех файлов в каталоге Fold:
var Files, s, SPath, FileExt, Status;
Files=new Enumerator(Fold.Files);
после чего все элементы коллекции просматриваются в цикле while:
s="";
//Цикл по всем файлам
while (!Files.atEnd()) {
…
Files.moveNext(); //Переходим к следующему файлу
}
Для текущего файла в коллекции выделяется его расширение, которое преобразуется к верхнему регистру:
//Определяем путь к файлу
SPath=Files.item().Path;
//Выделяем расширение файла
FileExt=FSO.GetExtensionName(SPath).toUpperCase();
В случае совпадения расширения
FileExt
с расширением SExt
в блоке try…catch
производится попытка удаления текущего файла:
ColTmp++; //Увеличиваем счетчик файлов для удаления
try {
Status="Ok";
//Пытаемся удалить файл
Files.item().Delete();
} catch (e) {
//Обрабатываем возможные ошибки
if (е != 0) {
//Произошла ошибка при удалении файла
Status="Busy";
}
}
Таким образом, в переменной
Status
будет записан результат удаления файла: "OK" в случае успеха, и "Busy" в том случае, если удаляемый файл занят другим приложением. После этого полный путь к удаляемому файлу и значение переменной Status
печатаются в окне Блокнота с помощью метода SendKeys
объекта WshShell
. Здесь только нужно учесть, что в имени файла могут встретиться символы, имеющие специальный смысл для метода SendKeys
, поэтому предварительно нужно соответствующим образом заменить такие символы в имени файла:
//Заменяем специальные символы в названии файла
SPath=SPath.replace("~", "{-}");
SPath=SPath.replace("+", "{+}");
SPath=SPath.replace("^", "{^}");
SPath=SPath.replace("%", "{%}");
//Посылаем название файла и результат его удаления в Блокнот
WshShell.SendKeys(SPath+"{TAB}"+Status+"~");
//Приостанавливаем сценарий на 0,5 сек
WScript.Sleep(500);
Перейдем теперь к описанию функции
LoopSubFolders(Fold)
. Сначала в этой функции удаляются временные файлы в каталоге Fold:
//Удаляем временные файлы из каталога Fold
DelFilesInFolder(Fold, ExtForDel);
Затем происходит удаление файлов во всех подкаталогах каталога Fold, причем делается это с помощью обращения для каждого подкаталога к той же функции
LoopSubFolders
:
//Создаем коллекцию подкаталогов
SubFolders = new Enumerator(Fold.SubFolders);
//Цикл по всем подкаталогам
while (!SubFolders.atEnd()) {
//Вызываем рекурсивно функцию LoopSubFolders
LoopSubFolders(SubFolders.item());
//Переходим к следующему подкаталогу
SubFolders.moveNext();
}
Полный текст сценария DelTmp.js приведен в листинге 5.17.
/*******************************************************************/
/* Имя: DelTmp.js */
/* Язык: JScript */
/* Описание: Удаление временных файлов во всех подкаталогах */
/* текущего каталога */
/*******************************************************************/
//Объявляем глобальные переменные
var WshShell,FSO,Folder,
ColTmp=0, //Счетчик файлов для удаления
ExtForDel="tmp"; //Расширение файлов, подлежащих удалению
//Рекурсивная функция для удаления временных файлов в каталоге Fold
function LoopSubFolders(Fold) {
var SubFolders;
//Удаляем временные файлы из каталога Fold
DelFilesInFolder(Fold,ExtForDel);
//Создаем коллекцию подкаталогов
SubFolders = new Enumerator(Fold.SubFolders);
//Цикл по всем подкаталогам
while (!SubFolders.atEnd()) {
//Вызываем рекурсивно функцию LoopSubFolders
LoopSubFolders(SubFolders.item());
//Переходим к следующему подкаталогу
SubFolders.moveNext();
}
}
//Функция для удаления файлов с расширением SExt в каталоге Fold
function DelFilesInFolder(Fold,SExt) {
//Объявляем переменные
var Files,s,SPath,FileExt,Status;
//Создаем коллекцию всех файлов в каталоге Fold
Files=new Enumerator(Fold.Files);
s="";
//Цикл по всем файлам
while (!Files.atEnd()) {
//Определяем путь к файлу
SPath=Files.item().Path;
//Выделяем расширение файла
FileExt=FSO.GetExtensionName(SPath).toUpperCase();
//Сравниваем расширение файла с расширением SExt
if (FileExt==SExt.toUpperCase()) {
ColTmp++; //Увеличиваем счетчик файлов для удаления
try {
Status="Ok";
//Пытаемся удалить файл
//Files.item().Delete();
} catch (e) { //Обрабатываем возможные ошибки
if (e != 0) {
//Произошла ошибка при удалении файла
Status="Busy";
}
}
//Заменяем специальные символы в названии файла
SPath=SPath.replace("~","{~}");
SPath=SPath.replace("+","{+}");
SPath=SPath.replace("^","{^}");
SPath=SPath.replace("%","{%}");
//Посылаем название файла и результат его удаления
//в Блокнот
WshShell.SendKeys(SPath+"{TAB}"+Status+"~");
//Приостанавливаем сценарий на 0,5 сек
WScript.Sleep(500);
}
Files.moveNext(); //Переходим к следующему файлу
}
}
/******************* Начало **********************************/
//Создаем объект WshShell
WshShell=WScript.CreateObject("WScript.Shell");
//Запускаем Блокнот
theNotepad = WshShell.Exec("Notepad");
//Приостанавливаем сценарий на 0,5 сек
WScript.Sleep(500);
//Активизируем окно Блокнота
WshShell.AppActivate(theNotepad.ProcessID);
//Создаем объект FileSystemObject
FSO=WScript.CreateObject("Scripting.FileSystemObject");
//Определяем каталог, с которого будет начато удаление файлов
Folder = FSO.GetFolder("D:\\");
//Вызываем функцию LoopSubFolder для каталога Folder
LoopSubFolders(Folder);
//Формируем информацию о количестве обработанных файлов
SItog="Total: "+ColTmp+ " file(s)";
//Посылаем в Блокнот итоговую информацию
WshShell.SendKeys(SItog);
/************* Конец *********************************************/
Всем хорошо известно, что для поиска файлов и папок с помощью стандартных средств Windows в именах можно использовать подстановочные символы "?" (обозначает любой один символ) и "*" (обозначает любое число любых символов). Например, на рис. 5.12 представлен результат поиска файлов *.sys (все файлы с расширением sys) на диске С:.
Рис. 5.12. Использование подстановочных символов при поиске файлов
В сценариях WSH можно производить поиск файлов (как и любого другого текста) с помощью гораздо более сложных правил для определения соответствий. Для этого используются регулярные выражения, которые определяют образец текста для поиска. Для задания этого образца используются литералы и метасимволы. Каждый символ, который не имеет специального значения в регулярных выражениях, рассматривается как литерал и должен точно совпасть при поиске. Метасимволы — это символы со специальным значением в регулярных выражениях. Описание наиболее часто используемых метасимволов приведено в табл. 5.14.
Таблица 5.14. Некоторые метасимволы, использующиеся в регулярных выражениях
Символы | Описание |
---|---|
|
Следующий символ будет являться специальным символом или, наоборот, литералом. Например, означает символ "n", а " " означает символ новой строки. Последовательности соответствует символ "\", а — символ "(" |
|
Начало строки |
|
Конец строки |
|
Предыдущий символ повторяется любое число раз (в том числе ни разу). Например, выражению соответствуют как "z", так и "zoo" |
|
Предыдущий символ повторяется не менее одного раза. Например, выражению соответствует "zoo", но не "z" |
|
Предыдущий символ повторяется не более одного раза |
(точка) |
Любой символ, кроме перевода строки |
|
Либо символ "х", либо символ "у". Например, выражению соответствуют "z" или "food" |
|
Множество символов. Означает любой один символ из набора символов, заключенных в квадратные скобки. Например, выражению соответствует символ "а" в слове "plain" |
|
Диапазон символов. Означает любой один символ из заданного диапазона. Например, выражению соответствует любая буква английского алфавита в нижнем регистре |
|
Означает любой символ, не входящий в заданный диапазон. Например, выражению соответствует любой символ, не попадающий в диапазон символов от "m" до "z" |
|
Граница слова, т.е. позиция между словом и пробелом. Например, выражению соответствует символ "er" в слове "never", но не в слове "verb" |
|
Позиция внутри слова (не на границе). Например, выражению соответствует подстрока "ear" в "never early" |
|
Символ, обозначающий цифру. Эквивалентно
|
|
Любой символ, кроме цифры. Эквивалентно
|
Метасимволы можно употреблять совместно, например, комбинация
".*"
означает любое число любых символов.
Более подробную информацию о регулярных выражениях можно найти, например, в документации Microsoft по языку VBScript.
В качестве примера использования регулярных выражений в листинге 5.18 приведен сценарий FindRegExp.js, в котором производится поиск в подкаталоге ForFind текущего каталога всех файлов, имена которых начинаются с символов "П", "А" или "И" и имеют расширение txt.
Для получения доступа к каталогу ForFind в сценарии используется метод
GetFolder
объекта FileSystemObject
:
//Создаем объект WshShell
WshShell=WScript.CreateObject("WScript.Shell");
//Создаем объект FileSystemObject
FSO=WScript.CreateObject("Scripting.FileSystemObject");
//Создаем объект Folder для доступа к подкаталогу ForFind
//текущего каталога
Folder = FSO.GetFolder(WshShell.CurrentDirectory+"\\ForFind");
Поиск нужных файлов будет выполняться с помощью следующего регулярного выражения:
//Создаем регулярное выражение (объект RegExp)
RegEx=new RegExp("^[ПАИ].*\.txt$", "i");
Сам поиск и вывод имен найденный файлов производятся в функции
FindFilesInFolder(Fold, RegEx)
. Здесь сначала инициализируются счетчик найденных файлов и переменная, в которой будут сохраняться имена найденных файлов, а также создается объект Enumerator
(переменная Files
) для доступа к файлам каталога Fold
:
ColFind=0; //Счетчик найденных файлов
SFileNames=""; //Строка с именами файлов
//Создаем коллекцию файлов в каталоге Fold
Files=new Enumerator(Fold.Files);
Элементы коллекции просматриваются в цикле
while
:
//Цикл по всем файлам в коллекции
while (!Files.atEnd()) {
Files.moveNext(); //Переходим к следующему файлу
}
Для текущего файла в коллекции выделяется его имя, которое затем с помощью метода
test
объекта RegExp
проверяется на соответствие заданному регулярному выражению:
//Выделяем имя файла
SName=Files.item().Name;
//Проверяем, соответствует ли имя файла регулярному выражению
if (RegEx.test(SName)) {
ColFind++; //Увеличиваем счетчик найденных файлов
//Добавляем имя файла к переменной SFileNames
SFileNames+=SName+ " \n";
}
В конце функции
FindFilesInFolder(Fold, RegEx)
на экран выводятся имена найденных файлов и их общее количество:
SItog="Найдено файлов: "+ColFind;
//Выводим на экран имена и количество найденных файлов
WScript.Echo(SFileNames+SItog);
/*******************************************************************/
/* Имя: FindRegExp.js */
/* Язык: JScript */
/* Описание: Поиск файлов, имена которых соответствуют заданному */
/* регулярному выражению */
/*******************************************************************/
//Объявляем переменные
var WshShell,FSO,Folder,ColFind,RegExp,SFileNames;
//Функция для поиска файлов в заданном каталоге
function FindFilesInFolder(Fold,RegEx) {
var Files,SName; //Объявляем переменные
ColFind=0; //Счетчик найденных файлов
SFileNames=""; //Строка с именами файлов
//Создаем коллекцию файлов в каталоге Fold
Files=new Enumerator(Fold.Files);
//Цикл по всем файлам в коллекции
while (!Files.atEnd()) {
//Выделяем имя файла
SName=Files.item().Name;
//Проверяем, соответствует ли имя файла регулярному
//выражению
if (RegEx.test(SName)) {
ColFind++; //Увеличиваем счетчик найденных файлов
//Добавляем имя файла к переменной SFileNames
SFileNames+=SName+"\n";
}
Files.moveNext(); //Переходим к следующему файлу
}
SItog="Найдено файлов: "+ColFind;
//Выводим на экран имена и количество найденных файлов
WScript.Echo(SFileNames+SItog);
}
/******************* Начало **********************************/
//Создаем объект WshShell
WshShell=WScript.CreateObject("WScript.Shell");
//Создаем объект FileSystemObject
FSO=WScript.CreateObject("Scripting.FileSystemObject");
//Создаем объект Folder для доступа к подкаталогу ForFind
//текущего каталога
Folder = FSO.GetFolder(WshShell.CurrentDirectory+"\\ForFind");
//Создаем регулярное выражение (объект RegExp)
RegExp=new RegExp("^[ПАИ].*\.txt$","i");
//Ищем файлы, имена которых соответствуют регулярному
//выражению RegExp в каталоге Folder
FindFilesInFolder(Folder,RegExp);
/************* Конец *********************************************/
Поставим перед собой следующую задачу. Пусть в заданный каталог на жестком диске (например, C:\In) поступают из почтовой программы или по локальной сети файлы с различными расширениями. Требуется выделить из них все файлы с заданным расширением (например, 003) и перенести их в другой каталог (например, C:\Out). При этом необходимо вести журнал операций (log-файл), в который для каждого переносимого файла записывать следующую информацию: имя файла, дату и время его создания, дату и время перемещения файла. Структура log-файла (в нашем случае это файл C:\In\log.txt) должна быть следующей:
Имя файла (Дата и время создания) Дата и время перемещения
Например:
34556.003 (19/10/2002 10:45) 19/10/2002 11:02
43432_KL.003 (19/10/2002 10:45) 19/10/2002 11:02
45.003 (19/10/2002 10:45) 19/10/2002 11:02
...
Кроме этого, во время перемещения файлов на экран должна выводиться информация о том, какой именно файл обрабатывается, а после завершения работы сценария нужно напечатать общее количество перемещенных файлов (рис. 5.13).
Рис. 5.13. Информация о перемещении файлов
Поставленную задачу выполняет рассматриваемый ниже сценарий MoveLog.js; запускать этот сценарий следует в консольном режиме с помощью cscript.exe.
Пути к каталогу-источнику, в котором первоначально находятся файлы, и к целевому каталогу, в который будут перемещены эти файлы, хранятся соответственно в переменных
Source
и Dest
:
var
Source="C:\\In\\", //Путь к каталогу-источнику файлов для перемещения
Dest="C:\\Out\\"; //Путь к целевому каталогу
В переменных
Mask
и PathLog
записаны соответственно расширение файлов для перемещения и путь к log-файлу:
var
Mask="003", //Расширение файлов для перемещения
PathLog="C:\\In\\log.txt"; //Путь к log-файлу
Сначала в сценарии с помощью метода
FolderExists
объекта FileSystemObject
проверяется наличие на диске каталога-источника; в случае отсутствия этого каталога выводится соответствующее сообщение и выполнение сценария прерывается:
//Создаем объект FileSystemObject
FSO=WScript.CreateObject("Scripting.FileSystemObject");
//Проверяем наличие каталога-источника
if (!FSO.FolderExists(Source)) {
//Выводим сообщение об отсутствии каталога-источника
WScript.Echo("Каталог-источник", Source, "не существует.");
WScript.Echo("Нажмите Enter...");
WScript.StdIn.ReadLine();
//Выходим из сценария
WScript.Quit();
}
Аналогичным образом проверяется наличие целевого каталога:
//Проверяем наличие целевого каталога
if (!FSO.FolderExists(Dest)) {
//Выводим сообщение об отсутствии целевого каталога
WScript.Echo("Целевой каталог", Dest, "не существует.");
WScript.StdIn.ReadLine();
WScript.StdIn.ReadLine();
//Выходим из сценария
WScript.Quit();
}
После этого создается объект
Enumerator
(переменная Files
) для доступа к коллекции всех файлов в каталоге-источнике:
//Создаем объект Folder для каталога-источника Fold=FSO.GetFolder(Source);
//Создаем объект Enumerator для доступа к коллекции файлов
//в каталоге-источнике
Files=new Enumerator(Fold.Files);
Операции записи информации в log-файл и непосредственно переноса файлов из одного каталога в другой реализованы соответственно в функциях
WriteLog()
и MoveFiles()
.
В функции
WriteLog()
после объявления переменных открывается log-файл в режиме добавления строк:
var s, ss, s1, d, File, FLog;
WScript.Echo(" ");
WScript.Echo("Записываем информацию в log-файл...");
//Открываем log-файл для добавления
FLog=FSO.OpenTextFile(PathLog, ForAppending, true);
Затем в цикле
while
происходит просмотр коллекции файлов в каталоге-источнике:
//Переходим к первому элементу коллекции файлов
Files.moveFirst();
//Цикл по всем файлам в коллекции
while (!Files.atEnd()) {
//Извлекаем текущий файл из коллекции
File=Files.item();
//Переходим к следующему файлу в коллекции
Files.moveNext();
}
Если файл подлежит перемещению (расширение этого файла совпадает с расширением файлов для перемещения), то определяется его имя (свойство Name), дата создания (свойство DateCreated) и текущая дата (объект Date), и в log-файл записывается соответствующая информация:
//Выделяем расширение файла
s=FSO.GetExtensionName(File.Name);
//Проверяем, совпадает ли расширение текущего файла
//с расширением файлов для перемещения
if (s==Mask) {
//Выводим имя файла на экран
WScript.Echo(" "+File.Name);
//Определяем дату создания файла
d=new Date(File.DateCreated);
//Формируем строку ss для записи в log-файл
ss=LFillStr(13,File.Name)
s1="("+DateToStr(d)+" ";
s1+=TimeToStr(d)+")";
ss+=LFillStr(20,s1);
//Определяем текущую дату
d=new Date();
ss+=DateToStr(d);
ss+=" "+TimeToStr(d);
//Записываем сформированную строку в log-файл
FLog.WriteLine(ss);
}
Записываемая в log-файл строка формируется в нужном виде с помощью вспомогательных функций
LFillStr
(выравнивание строки влево в поле заданной длины), DateToStr
(формирование из объекта Date строки формата ДД/ММ/ГГГГ) и TimeTostr
(формирование из объекта Date строки формата ЧЧ:ММ).
В функции
MoveFiles()
, как и в WriteLog()
, производится перебор в цикле while
файлов каталога-источника (элементов коллекции Files). Перемещение файлов осуществляется с помощью последовательного применения методов Copy
и Delete
:
Files.moveFirst();
//Цикл по всем файлам в коллекции
while (!Files.atEnd()) {
//Извлекаем текущий файл из коллекции
File=Files.item();
//Выделяем расширение файла
s=FSO.GetExtensionName(File.Name);
//Проверяем, совпадает ли расширение текущего файла
//с расширением файлов для перемещения
if (s==Mask) {
//Выводим имя файла на экран
WScript.Echo(" "+File.name);
//Копируем файл в целевой каталог
File.Copy(Dest);
//Удаляем файл
File.Delete();
//Увеличиваем счетчик количества перемещенных файлов
Col++;
}
//Переходим к следующему файлу в коллекции
Files.moveNext();
}
После перемещения всех файлов на экран выводится информация об их количестве:
WScript.Echo("Перемещено файлов:", Col);
WScript.Echo("Нажмите Enter...");
WScript.StdIn.ReadLine();
Полный текст сценария MoveLog.js приведен в листинге 5.19.
/*******************************************************************/
/* Имя: MoveLog.js */
/* Язык: JScript */
/* Описание: Перемещение файлов из каталога-источника в */
/* целевой каталог с ведением log-файла */
/*******************************************************************/
//Объявляем переменные
var
Source="C:\\In\\", //Путь к каталогу-источнику файлов для перемещения
Dest="C:\\Out\\", //Путь к целевому каталогу
Mask="003", //Расширение файлов для перемещения
PathLog="C:\\In\\log.txt", //Путь к log-файлу
ForAppending=8; //Константа для работы с файлами
//Объявляем переменные
var FSO,Fold,Files;
//Функция для записи информации в log-файл
function WriteLog() {
//Объявляем переменные
var s,ss,s1,d,File,FLog;
WScript.Echo("");
WScript.Echo("Записываем информацию в log-файл...");
//Открываем log-файл для добавления
FLog=FSO.OpenTextFile(PathLog,ForAppending,true);
//Переходим к первому элементу коллекции файлов
Files.moveFirst();
//Цикл по всем файлам в коллекции
while (!Files.atEnd()) {
//Извлекаем текущий файл из коллекции
File=Files.item();
//Выделяем расширение файла
s=FSO.GetExtensionName(File.Name);
//Проверяем, совпадает ли расширение текущего файла
//с расширением файлов для перемещения
if (s==Mask) {
//Выводим имя файла на экран
WScript.Echo(" "+File.Name);
//Определяем дату создания файла
d=new Date(File.DateCreated);
//Формируем строку ss для записи в log-файл
ss=LFillStr(13,File.Name)
s1="("+DateToStr(d)+" ";
s1+=TimeToStr(d)+")";
ss+=LFillStr(20,s1);
//Определяем текущую дату
d=new Date();
ss+=DateToStr(d);
ss+=" "+TimeToStr(d);
//Записываем сформированную строку в log-файл
FLog.WriteLine(ss);
}
//Переходим к следующему файлу в коллекции
Files.moveNext();
}
}
//Функция для перемещения файлов
function MoveFiles() {
//Объявляем переменные
var s,ss,Col,File;
Col=0; //Счетчик количества перемещенных файлов
WScript.Echo("");
WScript.Echo("Перемещаем файлы ...");
//Переходим к первому элементу коллекции файлов
Files.moveFirst();
//Цикл по всем файлам в коллекции
while (!Files.atEnd()) {
//Извлекаем текущий файл из коллекции
File=Files.item();
//Выделяем расширение файла
s=FSO.GetExtensionName(File.Name);
//Проверяем, совпадает ли расширение текущего файла
//с расширением файлов для перемещения
if (s==Mask) {
//Выводим имя файла на экран
WScript.Echo(" "+File.name);
//Копируем файл в целевой каталог
File.Copy(Dest);
//Удаляем файл
File.Delete();
//Увеличиваем счетчик количества перемещенных файлов
Col++;
}
//Переходим к следующему файлу в коллекции
Files.moveNext();
}
//Выводим информацию о количестве перемещенных файлов
WScript.Echo("");
WScript.Echo("Перемещено файлов:",Col);
WScript.Echo("Нажмите Enter...");
WScript.StdIn.ReadLine();
}
/******************* Начало **********************************/
//Создаем объект FileSystemObject
FSO=WScript.CreateObject("Scripting.FileSystemObject");
//Проверяем наличие каталога-источника
if (!FSO.FolderExists(Source)) {
//Выводим сообщение об отсутствии каталога-источника
WScript.Echo("Каталог-источник",Source,"не существует.");
WScript.Echo("Нажмите Enter...");
WScript.StdIn.ReadLine();
//Выходим из сценария
WScript.Quit();
}
//Проверяем наличие целевого каталога
if (!FSO.FolderExists(Dest)) {
//Выводим сообщение об отсутствии целевого каталога
WScript.Echo("Целевой каталог",Dest,"не существует.");
WScript.StdIn.ReadLine();
WScript.StdIn.ReadLine();
//Выходим из сценария
WScript.Quit();
}
//Создаем объект Folder для каталога-источника
Fold=FSO.GetFolder(Source);
//Создаем объект Enumerator для доступа к коллекцию файлов
//в каталоге-источнике
Files=new Enumerator(Fold.Files);
//Записываем информацию в log-файл
WriteLog();
//Перемещаем файлы в целевой каталог
MoveFiles();
/************* Конец *********************************************/
// Вспомогательные функции
//Дополнение строки ss ведущими нулями до длины ll
function LeadZero(ll,ss) {
var i,s,l1;
s=ss.toString();
l1=s.length;
if (l1<=ll) {
for (i=1;i<=ll-l1;i++) s="0"+s;
}
return(s);
}
//Формирование из объекта Date строки формата ДД/ММ/ГГГГ
function DateToStr(dd) {
var s;
s=LeadZero(2,dd.getDate())+"/";
s+=LeadZero(2,dd.getMonth()+1)+"/";
s+=dd.getYear();
return(s);
}
//Формирование из объекта Date строки формата ЧЧ:ММ
function TimeToStr(dd) {
var s;
s=LeadZero(2,dd.getHours())+":"+LeadZero(2,dd.getMinutes());
return(s);
}
//Выравнивание строки s влево в поле длиной l символов
function LFillStr(l,s) {
var ss,i,ll;
ll=l-s.length;
if (s.length>=l) {
return(s);
} else {
ss=s;
for (i=1;i<=ll;i++) {
ss=ss+" ";
}
return(ss);
}
}
Последний пример, который мы рассмотрим в этой главе, посвящен обработке данных, хранящихся в текстовом файле с разделителями (это может быть, например, выборка из электронной таблицы, базы данных и т.п.).
Предположим, что имеется файл book.txt, содержащий информацию из записной книжки в следующем формате:
Фамилия|Имя|Телефон|Улица|Дом|Кв.|Примечание
В качестве примера мы будем рассматривать файл book.txt, приведенный в листинге 5.20.
Потапов|Сергей|55-55-55|Моховая|3|10|Без примечаний
Попов|Андрей|56-56-56|Ленина|3|5|Без примечаний
Иванов|Иван|17-17-17|Садовая|4|6|Очень хороший человек
Казаков|Сергей|24-19-68|Полежаева|101|22|Тоже очень хороший человек
Ниже приведен сценарий SortName.js, который реализует одну из функций для работы с записной книжкой — в результате работы этого сценария все записи из book.txt сортируются по фамилии и отображаются в Блокноте (рис. 5.14).
Опишем кратко алгоритм работы сценария SortName.js.
1. Информация из файла book.txt считывается в массив
PersonArr
. Каждый элемент массива является объектом типа Person
, в котором хранятся все данные для одного человека.
2. Массив
PersonArr
сортируется в нужном порядке (в нашем случае — по возрастанию фамилий).
3. Содержимое всех записей из массива
PersonArr
выводится в текстовый файл out.txt.
4. Файл out.txt открывается в Блокноте.
Как мы видим, взаимодействие с текстовым файлом данных происходит только при загрузке его содержимого в массив. Поэтому остальная часть сценария не зависит от формата файла с данными и может в дальнейшем применяться без изменений для обработки файлов в XML-формате.
Рис. 5.14. Содержимое записной книжки (сортировка по фамилии)
Запускной функцией в SortName.js является функция
Main()
:
function Main() {
//Создаем объект WshShell
WshShell = WScript.CreateObject("WScript.Shell");
//Определяем пути к файлам
InitPath();
//Создаем объект FileSystemObject
FSO=WScript.CreateObject("Scripting.FileSystemObject");
//Открываем выходной файл для записи
FOut=FSO.OpenTextFile(PathOut,ForWriting,true);
//Печатаем заголовок отчета
TopReport("Сортировка по фамилии");
//Выводим содержимого файла с данными
ListFile();
//Печатаем итоговую информацию
BottomReport();
//Открываем выходной файл в Блокноте
MakeOut();
}
Итак, основная работа по формированию выходного файла, который затем будет открыт в Блокноте, производится в функции
ListFile()
. В свою очередь, в этой функции вызываются функции FileToArray()
и ListPersonArray()
.
function ListFile() {
//Считывание данных из файла в массив
FileToArray();
//Запись информации из массива в выходной файл
ListPersonArray();
}
Опишем сначала функцию
FileToArray()
. Здесь производится создание массива PersonArr
, чтение в цикле while
строк из файла book.txt (с помощью метода ReadLine
) и формирование массива ss
(с помощью метода split
), элементы которого содержат данные для текущей записи. После этого вызывается функция PersonToArray()
для создания нового элемента массива PersonArr
:
function FileToArray() {
var s,ss;
//Открываем файл с данными для чтения
FBook=FSO.OpenTextFile(PathBook,ForReading,true);
//Создаем массив PersonArr
PersonArr=new Array();
//Читаем содержимое файла FBook
while (!FBook.AtEndOfStream) {
//Считываем строку
s=FBook.ReadLine();
//Записываем содержимое строки s в массив ss
ss = s.split("|");
//Добавляем новый элемент в массив объектов Person
PersonToArray(ss);
}
//Закрываем файл
FBook.Close();
}
В функции
PersonToArray(sArr)
из элементов массива sArr
формируется экземпляр PersonRec
объекта Person
. После этого объект PersonRec
добавляется в массив PersonArr
:
function PersonToArray(sArr) {
//Создаем новый объект Person
PersonRec=new Person(sArr[0], sArr[1], sArr[2], sArr[3], sArr[4], sArr[5], sArr[6]);
//Сохраняем объект Person в массиве
PersonArr[PersonArr.length]=PersonRec;
}
Конструктор объекта
Person
имеет следующий вид:
function Person(LastName,Name,Phone,Street,House,App,Note) {
this.LastName=LastName; //Фамилия
this.Name=Name; //Имя
this.Phone=Phone; //Телефон
this.Street=Street; //Улица
this.House=House; //Дом
this.App=App; //Квартира
this.Note=Note; //Примечание
}
Перейдем теперь к рассмотрению функции
ListPersonArray()
:
function ListPersonArray() {
var i;
//Сортировка массива по фамилии
PersonArr.sort(SortLastName);
//Цикл по всем элементам массива PersonArr
for (i=0;i<=PersonArr.length-1;i++) {
//Запись информации в выходной файл
PrintPerson(PersonArr[i]);
}
}
Сначала здесь производится сортировка массива
PersonArr
в возрастающем порядке по фамилиям, для чего в качестве параметра метода sort
указывается имя SortLastName
функции, которая производит сравнение двух элементов массива:
function SortLastName(Pers1,Pers2) {
if (Pers1.LastName
else if (Pers1.LastName==Pers2.LastName) return 0;
else return 1;
}
Сортировать массивы подобным образом можно только в сценариях JScript, где массивы рассматриваются как объекты. В сценариях VBScript отсутствуют встроенные средства для сортировки массивов
После сортировки массива содержимое его элементов в цикле выводится в файл out.txt с помощью функции
PrintPerson(PersRec)
:
function PrintPerson(PersRec) {
FOut.WriteLine("Фамилия : "+PersRec.LastName);
FOut.WriteLine("Имя : "+PersRec.Name);
FOut.WriteLine("Телефон: "+PersRec.Phone);
FOut.WriteLine("Улица: "+PersRec.Street);
FOut.WriteLine("Дом: "+PersRec.House);
FOut.WriteLine("Кв.: "+PersRec.App);
FOut.WriteLine("Заметки: "+PersRec.Note);
FOut.WriteLine("*********************************");
//Увеличиваем счетчик числа записей
NomRec++;
}
В листинге 5.21 приводится полный текст сценария SortName.js.
/*******************************************************************/
/* Имя: SortName.js */
/* Язык: JScript */
/* Описание: Записная книжка (данные в текстовом файле book.txt). */
/* Вывод всех записей с сортировкой по фамилии */
/*******************************************************************/
//Объявляем переменные
var
WshShell,FSO,
BasePath, //Путь к текущему каталогу
PathBook, //Путь к файлу с данными
PathOut, //Путь к выходному файлу
FBook, //Файл с данными
FOut, //Выходной файл
NomRec=0, //Счетчик количества записей
PersonRec, //Объект для хранения данных об одном человеке
PersonArr; //Массив для хранения объектов PersonRec
//Инициализируем константы для работы с файлами
var
ForReading=1,
ForWriting=2;
//Конструктор объекта Person
function Person(LastName,Name,Phone,Street,House,App,Note) {
this.LastName=LastName; //Фамилия
this.Name=Name; //Имя
this.Phone=Phone; //Телефон
this.Street=Street; //Улица
this.House=House; //Дом
this.App=App; //Квартира
this.Note=Note; //Примечание
}
//Заполнение нового элемента массива
function PersonToArray(sArr) {
//Создаем новый объект Person
PersonRec=new Person(sArr[0], sArr[1], sArr[2], sArr[3], sArr[4], sArr[5], sArr[6]);
//Сохраняем объект Person в массиве
PersonArr[PersonArr.length]=PersonRec;
}
//Создание массива объектов Person
function FileToArray() {
var s,ss;
//Открываем файл с данными для чтения
FBook=FSO.OpenTextFile(PathBook,ForReading,true);
//Создаем массив PersonArr
PersonArr=new Array();
//Читаем содержимое файла FBook
while (!FBook.AtEndOfStream) {
//Считываем строку
s=FBook.ReadLine();
//Записываем содержимое строки s в массив ss
ss = s.split("|");
//Добавляем новый элемент в массив объектов Person
PersonToArray(ss);
}
//Закрываем файл
FBook.Close();
}
//Запись в выходной файл итоговой информации
function TopReport(Mess) {
FOut.WriteLine(Mess);
FOut.WriteLine("--------------------");
FOut.WriteLine("");
}
//Запись в выходной файл итоговой информации
function BottomReport() {
FOut.WriteLine("Всего записей: "+NomRec);
}
//Запись данных из объекта Person в выходной файл
function PrintPerson(PersRec) {
FOut.WriteLine("Фамилия : "+PersRec.LastName);
FOut.WriteLine("Имя : "+PersRec.Name);
FOut.WriteLine("Телефон: "+PersRec.Phone);
FOut.WriteLine("Улица: "+PersRec.Street);
FOut.WriteLine("Дом: "+PersRec.House);
FOut.WriteLine("Кв.: "+PersRec.App);
FOut.WriteLine("Заметки: "+PersRec.Note);
FOut.WriteLine("*********************************");
//Увеличиваем счетчик числа записей
NomRec++;
}
//Сортировка массива и вывод его содержимого в выходной файл
function ListPersonArray() {
var i;
//Сортировка массива по фамилии
PersonArr.sort(SortLastName);
//Цикл по всем элементам массива PersonArr
for (i=0;i<=PersonArr.length-1;i++) {
//Запись информации в выходной файл
PrintPerson(PersonArr[i]);
}
}
//Функция для сортировки массива по фамилии
function SortLastName(Pers1,Pers2) {
if (Pers1.LastName
else if (Pers1.LastName==Pers2.LastName) return 0;
else return 1;
}
//Вывод содержимого файла с данными
function ListFile() {
//Считывание данных из файла в массив
FileToArray();
//Запись информации из массива в выходной файл
ListPersonArray();
}
//Просмотр содержимого выходного файла в Блокноте
function MakeOut() {
//Закрываем выходной файл
FOut.Close();
//Открываем выходной файл в Блокноте
WshShell.Run("notepad "+PathOut,1);
}
//Построение путей к файлам
function InitPath() {
BasePath=WshShell.CurrentDirectory+"\\";
//Путь к файлу с данными
PathBook=BasePath+"book.txt",
//Путь к выходному файлу
PathOut=BasePath+"out.txt";
}
//Основная запускная функция
function Main() {
//Создаем объект WshShell
WshShell = WScript.CreateObject("WScript.Shell");
//Определяем пути к файлам
InitPath();
//Создаем объект FileSystemObject
FSO=WScript.CreateObject("Scripting.FileSystemObject");
//Открываем выходной файл для записи
FOut=FSO.OpenTextFile(PathOut,ForWriting,true);
//Печатаем заголовок отчета
TopReport("Сортировка по фамилии");
//Выводим содержимого файла с данными
ListFile();
//Печатаем итоговую информацию
BottomReport();
//Открываем выходной файл в Блокноте
MakeOut();
}
/******************* Начало **********************************/
Main();
/************* Конец *********************************************/