|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Глава 5 Доступ из сценариев к файловой системе Сценарии 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 Объект 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
Сами названия методов объекта FileSystemObjectдовольно прозрачно указывают на выполняемые ими действия. Приведем необходимые пояснения и примеры для перечисленных методов. Методы CopyFile и CopyFolder Для копирования нескольких файлов или каталогов в последнем компоненте параметра FSO = WScript.CreateObject("Scripting.FileSystemObject"); FSO.CopyFile("с:\\mydocuments\\letters\\*.doc", "с:\\tempfolder\\"); А так писать нельзя: FSO = WScript.CreateObject("Scripting.FileSystemObject"); FSO.CopyFile("с:\\mydocuments\\*\\R1???97.xls", "с:\\tempfolder"); Необязательный параметр destination( overwrite=true) или нет ( overwrite=false). При использовании методов CopyFileи CopyFolderпроцесс копирования прерывается после первой возникшей ошибки (как и в команде COPYоперационной системы). Метод CreateTextFile Параметр overwriteравно true, то такой файл перепишется (старое содержимое будет утеряно), если же в качестве overwriteуказано false, то файл переписываться не будет. Если этот параметр вообще не указан, то существующий файл также не будет переписан. Параметр true, то файл создается в формате Unicode, если же unicodeравно falseили этот параметр вообще не указан, то файл создается в режиме ASCII. Для дальнейшей работы с созданным файлом, т.е. для записи или чтения информации, нужно использовать методы объекта TextStream. Соответствующий пример сценария приведен в листинге 5.1. Листинг 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(); /************* Конец *********************************************/ Методы DeleteFile и DeleteFolder Параметры Если параметр falseили не указан вовсе, то с помощью методов DeleteFileили DeleteFolderбудет нельзя удалить файл/каталог с атрибутом "только для чтения" (read-only). Установка для forceзначения trueпозволит сразу удалять такие файлы/каталоги. Замечание Если заданный для удаления файл/каталог не будет найден, то возникнет ошибка. Метод DriveExists Для дисководов со съемными носителями метод DriveExistsвернет trueдаже в том случае, если носитель физически отсутствует. Для того чтобы определить готовность дисковода, нужно использовать свойство IsReadyсоответствующего объекта Drive. В качестве примера использования метода DriveExistsприведем функцию ReportDriveStatus, которая возвращает информацию о наличии диска, передаваемого в эту функцию в качестве параметра (листинг 5.2). Листинг 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будет возвращать информацию о наличии диска, передаваемого в эту функцию в качестве параметра. Метод GetAbsolutePathName Для иллюстрации работы этого метода предположим, что текущим каталогом является C:\MyDocuments\Reports. В табл. 5.3 приведены значения, возвращаемые методом GetAbsolutePathName, при различных значениях параметра pathspec. Таблица 5.3. Варианты работы метода
Метод GetBaseName Работу этого метода иллюстрирует сценарий BaseName.js, приведенный в листинге 5.3. В результате выполнения этого сценария на экран выводится диалоговое окно, в котором отражены полный путь к файлу и базовое имя, выделенное из этого пути (рис. 5.1). Рис. 5.1. Полный путь к файлу и базовое имя для этого пути Листинг 5.3. Выделение базового имени файла /*******************************************************************/ /* Имя: 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); /************* Конец *********************************************/ Метод GetDrive Параметр С"), буквой с двоеточием (" С:"), буквой с двоеточием и символом разделителя пути (" С:\\"). Для сетевого диска drivespec можно указывать в формате UNC (например, " Server1\\Programs"). Если параметр GetDriveвозникнет ошибка. Если вам требуется преобразовать строку, содержащую обычный путь к файлу или каталогу, в вид, пригодный для GetDrive, необходимо применять методы GetAbsolutePathNameи GetDriveName: DriveSpec = GetDriveName(GetAbsolutePathName(Path)) Метод GetParentFolderName Для иллюстрации работы этого метода запустим сценарий ParentFolder.js (листинг 5.4). В результате будет выведено диалоговое окно с полным путем к файлу и путь к родительскому каталогу этого файла (рис. 5.2). Рис. 5.2. Полный путь к файлу и родительский каталог этого файла Листинг 5.4. Определение родительского каталога для файла /*******************************************************************/ /* Имя: 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); /************* Конец *********************************************/ Метод GetSpecialFolder Параметр Таблица 5.4. Значения параметра folderspec
Метод GetTempName Метод GetTempNameтолько возвращает имя файла, но не создает его. Для создания файла можно воспользоваться методом CreateTextFile, подставив в качестве параметра этого метода сгенерированное случайное имя (листинг 5.5). Листинг 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); /************* Конец *********************************************/ Методы MoveFile и MoveFolder Как и при использовании методов CopyFileи CopyFolder, для перемещения нескольких файлов или каталогов в последнем компоненте параметра sourceможно указывать групповые символы (? и *); в параметре destinationгрупповые символы недопустимы. При использовании методов MoveFileи MoveFolderпроцесс перемещения прерывается после первой возникшей ошибки (как и в команде move операционной системы). Перемещать файлы и каталоги с одного диска на другой нельзя. Метод OpenTextFile Числовой параметр Таблица 5.5. Параметр
Параметр true, то этот файл создастся, если же в качестве значения create указано falseили параметр createопущен, то файл создаваться не будет. Числовой параметр Таблица 5.6. Параметр
Для дальнейшей работы с открытым файлом, т.е. для записи или чтения информации, нужно использовать методы объекта TextStream. В следующем примере с помощью метода OpenTextFileтекстовый файл открывается в режиме добавления информации (листинг 5.6). Листинг 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(); /************* Конец *********************************************/ Замечание Объект Drive С помощью объекта Driveможно получить доступ к свойствам заданного локального или сетевого диска. Создается объект Driveс помощью метода GetDriveобъекта FileSystemObjectследующим образом: var FSO, D; FSO = WScript.CreateObject("Scripting.FileSystemObject"); D = FSO.GetDrive("C:"); Также объекты Driveмогут быть получены как элементы коллекции Drives. Свойства объекта Driveпредставлены в табл. 5.7; методов у этого объекта нет. Таблица 5.7. Свойства объекта
В листинге 5.7 приведен сценарий DriveInfo.js, в котором объект Driveиспользуется для доступа к некоторым свойствам диска С: (рис. 5.3). Рис. 5.3. Свойства диска С: Листинг 5.7. Получение свойств диска С /*******************************************************************/ /* Имя: 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 Доступная только для чтения коллекция 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. Список всех дисков, имеющихся в системе Листинг 5.8. Построение списка всех имеющихся дисков /*******************************************************************/ /* Имя: 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 Объект 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используется для получения даты создания каталога (листинг 5.9). Листинг 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. Методы объекта
Приведем необходимые замечания для методов из табл. 5.9. Метод Copy Обязательный параметр Параметр overwrite=true) или нет ( overwrite=false). Замечание Метод Delete Если параметр falseили не указан, то с помощью метода Deleteбудет нельзя удалить каталог с атрибутом "только для чтения" (read-only). Установка для force значения true позволит сразу удалять такие каталоги. При использовании метода Deleteневажно, является ли заданный каталог пустым или нет — он удалится в любом случае. Замечание Метод Move Обязательный параметр Замечание Коллекция Folders Коллекция 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, который создает в каталоге "С:\Мои документы" подкаталог "Новая папка". Листинг 5.10. Создание нового каталога /*******************************************************************/ /* Имя: 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("Новая папка"); /************* Конец *********************************************/ Замечание Для доступа ко всем элементам коллекции нужно использовать, как обычно, объект Enumerator. Например, в листинге 5.11 приведен сценарий ListSubFold.js, в котором на экран выводятся названия всех подкаталогов каталога C:\Program Files (рис. 5.5). Рис. 5.5. Список всех подкаталогов каталога C:\Program Files Листинг 5.11. Построение списка подкаталогов /*******************************************************************/ /* Имя: 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 Объект 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
Методы объекта Fileпредставлены в табл. 5.11. Таблица 5.11. Методы объекта
Приведем необходимые замечания для методов из табл. 5.11. Метод Copy Обязательный параметр Параметр overwrite=true) или нет ( overwrite=false). В листинге 5.12 приведен сценарий CopyFile.js, иллюстрирующий использование метода Сору. В этом сценарии на диске С: создается файл TestFile.txt, который затем копируется на рабочий стол. Листинг 5.12. Создание текстового файла и копирование его в другой каталог/*******************************************************************/ /* Имя: 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); /************* Конец *********************************************/ Замечание Метод Delete Если параметр falseили не указан, то с помощью метода Deleteбудет нельзя удалить файл с атрибутом "только для чтения" (read-only). Установка для forceзначения trueпозволит сразу удалять такие файлы. Замечание Метод Move Обязательный параметр Замечание Метод OpenAsTextStream Числовой параметр OpenTextFileобъекта FileSystemObject(табл. 5.5). Числовой параметр OpenTextFileобъекта FileSystemObject(табл. 5.6). Замечание В листинге 5.13 приведен сценарий WriteTextFile.js, иллюстрирующий использование метода OpenAsTextStream для записи строки в файл и чтения из него. Листинг 5.13. Запись информации в текстовый файл и чтение ее из него/*******************************************************************/ /* Имя: 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 Коллекция 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. Список всех файлов в специальной папке "Мои документы" Листинг 5.14. Построение списка файлов /*******************************************************************/ /* Имя: 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обеспечивает последовательный (строка за строкой) доступ к текстовому файлу. Методы этого объекта позволяют читать информацию из файла и записывать ее в него. Создать объект 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представлены в табл. 5.13. Таблица 5.13. Методы объекта
В листинге 5.15 приведен сценарий TextFile.js, иллюстрирующий использование методов объекта TextStream. В этом сценарии на диске С: создается файл TestFile.txt и в него записываются три строки, вторая из которых является пустой. После этого файл открывается для чтения и из него считывается третья строка, которая выводится на экран (рис. 5.7). Рис. 5.7. Результат работы сценария TextFile.js Листинг 5.15. Работа с текстовым файлом с помощью методов объекта TextStream /*******************************************************************/ /* Имя: 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, который будет создавать таблицу использования дискового пространства для дисков всех типов (съемных, жестких и сетевых), имеющихся на компьютере, в следующем формате:
Для этого в сценарии вывод информации производится в текстовый файл rep.txt (переменная RepFile), который затем открывается с помощью Блокнота (рис. 5.8): //Создаем объект WshShell WshShell=WScript.CreateObject("WScript.Shell"); //Запускаем Блокнот (notepad.exe) и открываем в нем файл rep.txt WshShell.Run("notepad.exe rep.txt"); Данные об одном диске формируются в функции WriteDriveInfo(drive), где в качестве параметра driveподставляется объект D rive для нужного диска. Соответствующие объекты 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("+---------------------------------------------------+"); Если же устройство 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. Листинг 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), затем выделить все файлы в этом списке и нажать комбинацию клавиш <Shift>+<Delete> (удаление файлов без помещения в Корзину). Однако если хотя бы один из временных файлов будет занят каким-либо приложением, то в доступе к нему будет отказано и процесс удаления прервется (рис. 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. Листинг 5.17. Удаление всех временных файлов на диске D:/*******************************************************************/ /* Имя: 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); /************* Конец *********************************************/ Поиск файлов с использованием регyлярных выражений Всем хорошо известно, что для поиска файлов и папок с помощью стандартных средств Windows в именах можно использовать подстановочные символы "?" (обозначает любой один символ) и "*" (обозначает любое число любых символов). Например, на рис. 5.12 представлен результат поиска файлов *.sys (все файлы с расширением sys) на диске С:. Рис. 5.12. Использование подстановочных символов при поиске файлов В сценариях WSH можно производить поиск файлов (как и любого другого текста) с помощью гораздо более сложных правил для определения соответствий. Для этого используются регулярные выражения, которые определяют образец текста для поиска. Для задания этого образца используются литералы и метасимволы. Каждый символ, который не имеет специального значения в регулярных выражениях, рассматривается как литерал и должен точно совпасть при поиске. Метасимволы — это символы со специальным значением в регулярных выражениях. Описание наиболее часто используемых метасимволов приведено в табл. 5.14. Таблица 5.14. Некоторые метасимволы, использующиеся в регулярных выражениях
Метасимволы можно употреблять совместно, например, комбинация ".*"означает любое число любых символов. Замечание В качестве примера использования регулярных выражений в листинге 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);Листинг 5.18. Поиск файлов, имена которых соответствуют регулярному выражению /*******************************************************************/ /* Имя: 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. Листинг 5.19. Поиск файлов с ведением log-файла/*******************************************************************/ /* Имя: 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. Листинг 5.20. Содержимое файла book.txtПотапов|Сергей|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<Pers2.LastName) return -1; else if (Pers1.LastName==Pers2.LastName) return 0; else return 1; } Замечание После сортировки массива содержимое его элементов в цикле выводится в файл 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. Листинг 5.21. Вывод содержимого записной книжки с сортировкой по фамилии/*******************************************************************/ /* Имя: 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<Pers2.LastName) return -1; 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(); /************* Конец *********************************************/ |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Главная | Контакты | Нашёл ошибку | Прислать материал | Добавить в избранное |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|