3. Работа с папками
Закончив с файлами, давайте рассмотрим работу с папками файловой системы.
3.1. Получение нужной папки
И в этом случае, перед тем как начать работу с папкой, нам следует получить её, точнее, экземпляр объекта, который её представляет.
3.1.1. Получение произвольной папки
Получить произвольную папку можно с помощью метода GetFolder объекта FileSystemObject. В качестве единственного параметра он принимает строку с полным путём к нужной нам папке.
Примечание:
Если мы зададим путь к несуществующей папке, то при выполнении Web-сценария получим сообщение об ошибке. Поэтому лучше перед получением папки проверить, действительно ли она существует на диске (об этом - позже).
Кроме того, если мы укажем путь к папке, расположенной на диске, который в это время ещё не готов к работе (например, привод компакт-дисков, в который не вставлен диск), то также получим ошибку. Поэтому перед доступом к такому диску следует проверить, готов ли он (как это сделать, будет описано далее).
А возвращает метод GetFolder экземпляр особого объекта под названием Folder. Этот объект представляет папку файловой системы.
var oFol = oFSO.GetFolder("c:\\Work");
Получаем папку Work диска C.
3.1.2. Получение системной папки
Некоторые папки файловой системы являются системными - они либо содержат компоненты операционной системы, либо зарезервированы для использования самой системой. Полные пути к таким папкам могут различаться в разных конфигурациях, поэтому для получения их используются специальные средства.
3.1.2.1. Получение системной папки средствами объекта FileSystemObject
Некоторые системные папки мы можем получить, воспользовавшись методом GetSpecialFolder объекта FileSystemObject. Вот формат его вызова:
<экземпляр объекта FileSystemObject>.GetSpecialFolder(
<номер системной папки>
);
В качестве единственного параметра указывается целочисленный номер системной папки, которую мы собираемся получить. Доступные номера перечислены ниже.
0 - папка, где установлена сама система. Обычно это папка Windows загрузочного диска.
1 - папка, где находятся компоненты системы. Обычно это папка Windows\System32 загрузочного диска.
2 - временная папка. Обычно это папка Windows\Temp загрузочного диска или папка Temp профиля текущего пользователя.
Метод GetSpecialFolder возвращает экземпляр объекта Folder, представляющего полученную системную папку.
var oFol = oFSO.GetSpecialFolder(2);
Получаем временную папку.
Как видим, с помощью метода GetSpecialFolder объекта FileSystemObject мы можем добраться только до трёх описанных выше системных папок. Получить, скажем, папку, представляющую Рабочий стол, или папку документов текущего пользователя мы, увы, не сможем.
3.1.2.2. Получение системной папки средствами объекта WScript.Shell
Для этого нам придётся задействовать другое средство WSH, о котором мы сейчас поговорим.
Перед тем как воспользоваться этим средством, мы должны создать экземпляр внешнего объекта WScript.Shell. Этот объект реализуется компонентом ActiveX и предоставляет доступ к некоторым возможностям оболочки Windows - Проводника.
var oWSS = new ActiveXObject("WScript.Shell");
Нам понадобится свойство SpecialFolders объекта WScript.Shell. Оно хранит экземпляр объекта-коллекции SpecialFolders, хранящего набор строк - путей к различным системным папкам. Да-да, обратившись к этому экземпляру объекта, мы получим путь к нужной нам системной папке в виде строки, а не представляющий эту папку экземпляр объекта Folder.
Для получения пути к системной папке применяется формат, схожий с форматом вызова метода:
<экземпляр объекта WScript.Shell>.SpecialFolders(
<обозначение системной папки>
);
Единственным параметром этому "методу" передаётся строка с обозначением нужной нам системной папки. Доступные обозначения и соответствующие им папки перечислены ниже.
AllUsersDesktop - папка Рабочего стола для всех пользователей.
AllUsersStartMenu - папка меню Пуск для всех пользователей.
AllUsersPrograms - папка меню Все программы для всех пользователей.
AllUsersStartup - папка меню Автозагрузка для всех пользователей.
Desktop - папка Рабочего стола текущего пользователя.
Как уже говорилось, данный "метод" возвращает путь к запрошенной папке в виде строки. Если такой папки в системе не существует (такое может случиться в старых версиях Windows), возвращается пустая строка.
var sPath = oWSS.SpecialFolders("AllUserDesktop");
if (sPath == "")
sPath = oWSS.SpecialFolders("Desktop");
var oFol = oFSO.GetFolder(sPath);
Сначала мы пытаемся получить путь к папке Рабочего стола для всех пользователей. Если же этой папки в системе нет, получаем путь к папке Рабочего стола текущего пользователя. Напоследок получаем экземпляр объекта Folder, представляющий эту папку.
3.2. Получение сведений о папке
Как и в случае с файлом, мы можем извлечь различные сведения о полученной ранее папке. Это выполняется с помощью различных свойств объекта Folder, которые мы сейчас рассмотрим. Почти все эти свойства доступны только для чтения; если какое-то из них доступно также и для записи, мы обязательно на это укажем.
Свойства Name, ShortName, Path, ShortPath, Drive, DateCreated, DateLastModified и DateLastAccessed нам уже знакомы по параграфу 2.2. Работают они так же, как и одноимённые свойства объекта File.
var sName = oFol.Name;
var sPath = oFol.Path;
var dCreated = oFol.DateCreated;
Свойство ParentFolder возвращает строку с полным путём к папке, в которой находится данная папка. При этом путь возвращается без конечного символа обратного слеша.
var sFolder = oFol.ParentFolder;
Свойство Type возвращает строку "Папка" для пустой папки и "Папка с файлами" для папки, имеющей файлы или другие папки. Польза от этого свойства в случае папки крайне сомнительна...
Свойство Size возвращает общий размер всех файлов, хранящихся в папке и вложенных в неё папках, в байтах в виде целого числа.
Свойство Attributes также знакомо нам по параграфу 2.2. Отметим только, что хранящееся в нём значение - сумма чисел, обозначающих установленные атрибуты, - всегда включает число 16 - признак того, что этот объект файловой системы является папкой.
А вот свойство IsRootFolder нам пока не знакомо. Оно возвращает true, если эта папка является корневой, и false в противном случае.
var oRootFol = oFSO.GetFolder("c:\\");
if (oRootFol.IsRootFolder)
//Это корневая папка
. . .
var oFol = oFSO.GetFolder("c:\\Work");
if (!(oFol.IsRootFolder))
//Это не корневая папка
3.3. Доступ к файлам и папкам, хранящимся в полученной папке
А ещё мы можем быстро получить доступ к файлам и папкам, что хранятся в полученной папке. Для этого используются два свойства объекта Folder и несколько весьма специфических объектов, разговор о которых сейчас и пойдёт.
Начнём со списка файлов, хранящихся в данной папке. Он хранится в доступном только для чтения свойстве Files объекта Folder и представляет собой экземпляр объекта Files.
Объект Files - особый. Мы можем рассматривать его как массив, содержащий экземпляры других объектов, в нашем случае - экземпляры объекта File, представляющих отдельные файлы. Такие объекты-массивы называются коллекциями.
var cFiles = oFol.Files;
Объект Files поддерживает свойство Count. Оно доступно только для чтения и возвращает количество элементов коллекции, то есть количество хранящихся в ней экземпляров объекта Files, в виде целого числа.
var iFilesCount = cFiles.Count;
Но как получить доступ к отдельным элементам этой коллекции? К сожалению, цикл for-in для этого не подходит; не подходит также и цикл for со счётчиком. (Автор проверял и то и другое, но получал только сообщения об ошибках...)
Единственный способ сделать это - воспользоваться экземпляром другого примечательного объекта, называемого Enumerator. Это внутренний, то есть реализуемый самим JavaScript, объект.
Сначала мы создадим экземпляр объекта Enumerator с помощью оператора new, указав в качестве единственного параметра его конструктора коллекцию, по элементам которой мы хотим "пройти".
var oEn = new Enumerator(cFiles);
После этого мы создадим цикл for, который будет при каждом проходе извлекать один из элементов указанной коллекции: первый, второй и т. д.
var oF = null;
for (; !oEn.atEnd(); oEn.moveNext()) {
oF = oEn.item();
. . .
}
Счётчик в этом цикле не нужен, поэтому первое выражение в цикле for, где он обычно создаётся, мы не указываем.
Объект Enumerator поддерживает особый внутренний указатель, помечающий элемент коллекции, который будет извлечён при очередной операции получения элемента коллекции (текущий элемент). Сразу после создания экземпляра этого объекта данный указатель установлен на самый первый элемент коллекции.
Не принимающий параметров метод atEnd объекта Enumerator возвращает true, если внутренний указатель установлен на конец коллекции, который находится за её последним элементом, то есть когда все элементы коллекции выбраны. Если же это не так, он возвращает false.
Другой не принимающий параметров метод этого же объекта - moveNext - переносит внутренний указатель на следующий элемент коллекции, делая его текущим. Результата он не возвращает.
Осталось рассмотреть третий метод объекта Enumerator - item. Он также не принимает параметров, а возвращает в качестве результата текущий элемент коллекции.
Так что, если мы выполним приведённый выше пример, мы будем получать в переменной oF очередной элемент коллекции cFiles - очередной файл, хранящийся в выбранной нами папке.
var oF = null;
var s = "";
for (; !oEn.atEnd(); oEn.moveNext()) {
oF = oEn.item();
s += oF.Path + "<BR>";
}
var oDivFiles = document.getElementById("divFiles");
oDivFiles.innerHTML = s;
Этот код поместит список полных путей к файлам, хранящихся в полученной нами папке, в контейнер divFiles. (Свойство innerHTML, поддерживаемое всеми объектами - элементами Web-страницы, возвращает или задаёт HTML-код, создающий содержимое этого элемента.)
Аналогичным образом можно получить доступ к папкам, находящимся в полученной папке. Только для этого будет нужно обратиться к доступному только для чтения свойству SubFolders объекта Folder, хранящее экземпляр объекта-коллекции Folders.
var cFolders = oFol.SubFolders;
var oEn = new Enumerator(cFolders);
var oF = null;
var s = "";
for (; !oEn.atEnd(); oEn.moveNext()) {
oF = oEn.item();
s += oF.Name + "<BR>";
}
var oDivFolders = document.getElementById("divFolders");
oDivFolders.innerHTML = s;
Этот код поместит список имён папок, хранящихся в полученной нами папке, в контейнер divFolders.
3.4. Создание файлов в полученной ранее папке
В предыдущей статье цикла, посвящённой файловому вводу-выводу, описывался метод CreateTextFile объекта FileSystemObject, выполняющий создание текстового файла с произвольном именем и в произвольной папке файловой системы. Мы пользовались этим методом, чтобы создать текстовый файл и сразу же открыть его для записи.
Так вот, этот же метод поддерживается объектом Folder. Формат его вызова точно такой же, как и в случае одноимённого метода объекта FileSystemObject, и работает он точно так же. За двумя исключениями...
В качестве первого параметра должна быть указана строка с именем создаваемого файла, а не путём к нему.
Метод выполняет создание файла с указанным именем прямо в данной папке.
Примечание:
Если первым параметром метода CreateTextFile объекта Folder указать полный путь к создаваемому файлу, при выполнении Web-сценария возникнет ошибка. (Что, впрочем, логично.)
var oFol = oFSO.GetFolder("c:\\Work");
var oTS = oFol.CreateTextFile("testfile.txt", true);
oTS.WriteLine("Test!!!");
oTS.Close();
Создаём файл testfile.txt в папке Work диска C и записываем в него строку "Test!!!".
3.5. Копирование, перемещение, переименование и удаление полученной ранее папки
В параграфе 2.3 мы рассмотрели методы Copy, Move и Delete и свойство Name объекта File, которые мы можем использовать, соответственно, для копирования, перемещения, удаления и переименования полученного ранее файла.
Объект Folder также поддерживает методы Copy, Move и Delete. Вызываются и работают они почти так же, как их "коллеги", принадлежащие объекту File, за исключением некоторых особенностей, перечисленных ниже.
Папки копируются, перемещаются и удаляются вместе со всем их содержимым.
В качестве первых параметров методов Copy и Move указываются пути к папкам назначения. Эти папки уже должны существовать на жёстком диске.
Если путь к папке назначения не завершается символом обратного слеша, будет скопировано или перемещено только содержимое папки.
Если же путь к папке назначения завершается символом обратного слеша, будет скопирована или перемещена сама папка.
oFol.Copy("c:\\Archive\\");
Копируем папку Work диска C в папку Archive. Поскольку в конце пути к папке назначения мы указали символ обратного слеша, будет скопирована сама папка. То есть в папке Archive будет создана папка Work со всем её содержимым - копия изначальной папки.
oFol.Move("c:\\Archive");
Копируем содержимое папки Work диска C в папку Archive. Поскольку в конце пути к папке назначения отсутствует символ обратного слеша, будет скопировано только содержимое нашей папки, но не сама папка. В результате в папке Archive появятся копии всех файлов и папок, находящихся в папке Work.
oFol.Delete();
А в параграфе 3.2 мы узнали, что объект Folder поддерживает свойство Name, с помощью которого мы можем переименовать папку.
oFol.Name = "Working";
3.6. Создание папки
Для создания новой папки обычно применяется метод CreateFolder объекта FileSystemObject. В качестве единственного параметра он принимает строку с путём к создаваемой папке и возвращает представляющий созданную папку экземпляр объекта Folder.
Примечание:
Если при вызове метода CreateFolder объекта FileSystemObject указать путь к уже имеющейся на диске папке, при выполнении Web-сценария возникнет ошибка.
Папка, в которой мы хотим создать нашу папку, уже должна существовать на диске. В противном случае мы получим сообщение об ошибке.
var oNewFol = oFSO.CreateFolder("c:\\Work\\!Test");
Создаём папку !Test в папке Work диска C. Поскольку папка Work уже существует, создание новой папки будет выполнено успешно.
var oNewFol2 = oFSO.CreateFolder("c:\\Work\\!Test2\\Other");
А это выражение вызовет ошибку выполнения, так как папка Work\!Test2 не существует на диске.
oFSO.CreateFolder("c:\\Work\\!Test2");
var oNewFol2 = oFSO.CreateFolder("c:\\Work\\!Test2\\Other");
Как говорится, не мытьём, так катаньем.
Поскольку метод CreateFolder возвращает экземпляр объекта Folder, представляющий созданную папку, мы можем сразу же создать в новой папке какий-либо файл или выполнить над ней какие-либо другие действия.
var oNewFol = oFSO.CreateFolder("c:\\Work\\!Test");
var oTS = oNewFol.CreateTextFile("!testfile.txt", true);
oTS.WriteLine("Test!!!");
oTS.Close();
Нужно сказать ещё об одном способе создания папки. С его помощью мы можем создать папку прямо внутри полученной нами ранее папки.
В параграфе 3.3 мы узнали, что объект Folder поддерживает свойство SubFolders. Это свойство хранит экземпляр объекта-коллекции Folders, представляющий все папки, что вложены в данную папку, в виде экземпляров объекта Folder.
Так вот, объект-коллекция Folders поддерживает метод Add. Он выполняет создание новой папки непосредственно в данной папке. В качестве единственного параметра он принимает строку с именем создаваемой папки и возвращает экземпляр объекта Folder, представляющий созданную папку.
Примечание:
Если при вызове метода Add объекта-коллекции Folders указать полный путь к создаваемой папке или указать имя уже существующей папки, при выполнении Web-сценария возникнет ошибка.
var oNewFol = oFol.SubFolders.Add("!Test");
3.7. Копирование, перемещение и удаление произвольной папки или папок
Рассмотренные нами в параграфе 3.5 методы позволяют скопировать, переместить или удалить полученную ранее папку. Если же мы хотим выполнить эти манипуляции с произвольной папкой или сразу с группой папок, нам придётся воспользоваться другими методами, о которых сейчас пойдёт разговор.
Примечание:
И в этом случае папки копируются, перемещаются и удаляются вместе со всем их содержимым.
Для копирования произвольной папки применяется метод CopyFolder объекта FileSystemObject. Формат его вызова таков:
<экземпляр объекта FileSystemObject>.CopyFolder(
<путь к копируемой папке>,
<путь к папке назначения>[,
<перезаписывать ли файлы, если они уже существуют>]
);
Первый параметр задаёт полный путь к копируемой папке в виде строки. В имени последней папки, присутствующей в этом пути, допускается использовать символы-маски * и ?, так что мы можем скопировать сразу несколько папок, удовлетворяющих определённому критерию.
Примечание:
Если мы укажем символы-маски в именах других папок пути к копируемой папке, при выполнении Web-сценария возникнет ошибка.
Второй параметр задаёт путь к папке назначения в виде строки. Если этот путь заканчивается символом обратного слеша (\) или если путь к копируемой папке содержит символы-маски, то в папку назначения будет скопирована сама папка (или папки); в противном случае в папку назначения будет скопировано только содержимое копируемой папки.
Примечание:
В случае указания путей к несуществующим папкам при выполнении Web-сценария возникнет ошибка. Также ошибка возникнет, если путь к копируемой папке, содержащий символы-маски, не указывает ни на одну папку.
Третий, необязательный, параметр позволяет указать, что Web-сценарий будет делать, если в папке назначения уже присутствует файл или папка с тем же именем, что и файл (папка) из содержимого копируемой папки. Значение true указывает перезаписать такой файл (папку), а значение false - не перезаписывать. Значение по умолчанию - true.
Примечание:
Если в папке назначения уже существует файл с тем же именем, что и копируемый, а мы отменили перезапись существующих файлов, то при выполнении Web-сценария возникнет ошибка.
Метод CopyFolder не возвращает результата.
oFSO.CopyFolder("c:\\Work\\!*", "c:\\Archive");
Копируем все папки, чьи имена начинаются с восклицательного знака, из папки Work в папку Archive диска C. Поскольку мы указали в пути к копируемой папке символ-маску *, будут скопированы сами эти папки.
oFSO.CopyFolder("c:\\Work", "c:\\Archive\\");
Копируем папку Work в папку Archive диска C. Здесь мы завершили путь к папке назначения символом обратного слеша, в результате в папку назначения будет скопирована сама эта папка.
oFSO.CopyFolder("c:\\Work", "c:\\Archive");
Копируем содержимое папки Work в папку Archive диска C. Здесь путь к папке назначения уже не завершается символом обратного слеша, поэтому в папку назначения будет скопировано только содержимое папки Work, но не сама эта папка.
Для перемещения произвольной папки мы используем метод MoveFolder объекта FileSystemObject. Формат его вызова таков:
<экземпляр объекта FileSystemObject>.MoveFolder(
<путь к перемещаемой папке>,
<путь к папке назначения>
);
Параметры этого метода аналогичны параметрам уже знакомого нам метода CopyFolder, и ведёт он себя так же.
oFSO.MoveFolder("c:\\Work\\*!", "c:\\Archive");
Перемещаем все папки, чьи имена начинаются с восклицательного знака, из папки Work в папку Archive диска C.
oFSO.MoveFolder("c:\\Work", "c:\\Archive\\");
Перемещаем папку Work в папку Archive диска C.
oFSO.MoveFolder("c:\\Work", "c:\\Archive");
Перемещаем содержимое папки Work в папку Archive диска C.
Для удаления произвольной папки служит метод DeleteFolder объекта FileSystemObject. Формат его вызова таков:
<экземпляр объекта FileSystemObject>.DeleteFolder(
<путь к удаляемой папке>[,
<удалить ли папки и файлы с установленным атрибутом "только для чтения">]
);
Первым, обязательным, параметром этому методу передаётся путь к удаляемой папке. Он должен быть представлен в виде строки. В имени последней папки в этом пути можно использовать символы-маски * и ?; то есть мы сможем удалить сразу несколько папок.
Второй, необязательный, параметр указывает, что делать в случае, если в содержимом удаляемой папки встретится файл или папка с установленным атрибутом "только для чтения". Значение true указывает, что следует всё равно удалить такой файл (папку), а значение false - не делать этого. Значение по умолчанию - false.
Метод DeleteFolder не возвращает результата.
Примечание:
При вызове метода DeleteFolder все файлы и папки будут удалены безвозвратно, без помещения в системную Корзину.
При попытке удаления несуществующей папки возникнет ошибка. Также ошибка возникнет, если путь к удаляемой папки, содержащий символы-маски, не указывает ни на одну папку.
oFSO.DeleteFolder("c:\\Work\\!*");
Удаляем из папки Work диска C все папки, чьи имена начинаются с восклицательного знака.
oFSO.DeleteFolder("c:\\Work");
Удаляем саму папку Work.
3.8. Проверка существования папки
Для проверки, существует ли на диске папка с указанным путём, можно использовать метод FolderExists объекта FileSystemObject. В качестве единственного параметра он принимает путь к папке в виде строки и возвращает true, если папка с этим путём существует, и false в противном случае.
var sFolderPath = "c:\\Work";
if (oFSO.FolderExists(sFolderPath))
oFSO.DeleteFolder(sFolderPath);
Сайт является источником уникальной информации о семействе операционных систем Windows и других продуктах Microsoft. Перепечатка материалов возможна только с разрешения редакции.
Работает на WMS 2.34 (Страница создана за 0.126 секунд (Общее время SQL: 0.112 секунд - SQL запросов: 53 - Среднее время SQL: 0.00211 секунд))