<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; JScript: Работа с ZIP-архивами: расширенная версия]]></title>
		<link>https://forum.script-coding.com/viewtopic.php?id=7124</link>
		<atom:link href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=7124&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «JScript: Работа с ZIP-архивами: расширенная версия».]]></description>
		<lastBuildDate>Thu, 19 Apr 2012 01:08:38 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[JScript: Работа с ZIP-архивами: расширенная версия]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=59543#p59543</link>
			<description><![CDATA[<p><em>Как уже сказано в сообщении #5 темы <a href="http://script-coding.com/forum/viewtopic.php?pid=58738#p58738">JScript: работа с ZIP архивами</a> предыдущая работа доступна но только в архиве &quot;Разработки&quot;. В настоящей теме предлагаю рассмотреть, обсудить и покритиковать новую версию класса для работы с ZIP-архивами. </em></p><p>Предыдущая версия успешно справлялась с задачей архивирования. Не более. Недавно я вернулся к ней и обнаружил, что иногда решение не работает - файлы не помещаются в архив. Была найдена причина - необходимо указывать полный путь до архивируемого файла. Сейчас код существенно переработан и позволяет выполнять многие действия с архивами ранее недоступные в предыдущей версии. </p><p>Вначале будет дано краткое описание API, показаны примеры использования, затем приведен исходный код и ссылка на актуальную версию библиотеки. Критика, замечания и багрепорты приветствуются. </p><p>***</p><p><strong>API библиотеки</strong><br /></p><div class="quotebox"><blockquote><p><strong>Конструктор</strong><br />ZipFile(name, create, overwrite)<br />Конструктор, создает новый объект для работы с архивами. Фактически вызывает метод ZipFile#open, который выполняет все необходимые действия</p><p><strong>Свойства</strong><br />ZipFile#name<br />Полный путь до архивного файла</p><p>ZipFile#file<br />Объект Folder, виртуальная папка проводника, реализующая доступ к архиву</p><p><strong>Методы</strong><br />ZipFile#open(name, create, overwrite)<br />Открывает архивный файл. Если аргумент create == true, то создается новый файл. Прежнее значение будет перезаписано, если указан аргумент overwrite == true. Инициализирует два свойства: </p><p>ZipFile#flush(timeout)<br />Сброс данных в архив. Метод-подделка необходима для создания задержки в timeout миллисекунд, чтобы предотвратить завершение скрипта раньше завершения создания архива. </p><p>ZipFile#forInput(input, func)<br />Метод используется для помещения объектов из массива input в архив. Для этого вторым аргументом передается функция, которая будет вызвана для каждого элемента массива. Функция использует два аргумента<br />1. объект File или Folder, который будет помещен в архив<br />2. объект Folder, виртуальная папка проводника, реализующая доступ к архиву</p><p>ZipFile#forEach(func)<br />Метод используется для работы с объектами внутри архива. Для работы с объектами методу передается функция, которая вызывается для каждого объекта в архиве. Функция использует два аргумента<br />1. объект File или Folder в архиве<br />2. объект Folder, виртуальная папка проводника, реализующая доступ к архиву</p></blockquote></div><p>***</p><p><strong>Пример 1. Создание ZIP-архива</strong><br /></p><div class="codebox"><pre><code>
var filename = &#039;test.zip&#039;;
var create = true;
var overwrite = true;

WScript.Echo(&#039;*** Create the file&#039;);
var zipfile = new ZipFile();
zipfile.open(filename, create, overwrite);

WScript.Echo(&#039;*** Put objects to the archive&#039;);
zipfile.forInput(
	[
		&#039;C:\\Logs&#039;, 
		&#039;C:\\tmp&#039;, 
	], 
	function(folderItem, arcfile)
	{
		WScript.Echo(folderItem.Path);

		arcfile.CopyHere(folderItem.Path, 0);
		WScript.Sleep(3000);
	}
);</code></pre></div><p>В этом примере создается архивный файл test.zip, в который будут помещены существующие каталоги C:\Log и C:\tmp. Существовавший до этого файл test.zip будет перезаписан. <br />Было замечено, что при увеличении размера архивного файла или архивировании большого количества файлов требуется некоторое время перед помещением следующего элемента. Поэтому используется задержка в 3 секунды после копирования файлов в архив. <br />Для копирования объектов в архив вызывается функция, которой передаются два аргумента:<br />1. объект File или Folder, который будет помещен в архив<br />2. объект Folder, виртуальная папка проводника, реализующая доступ к архиву</p><br /><p><strong>Пример 2. Чтение списка файлов из архива</strong><br /></p><div class="codebox"><pre><code>
var filename = &#039;test.zip&#039;;

WScript.Echo(&#039;*** Open the file&#039;);
var zipfile = new ZipFile(filename);

WScript.Echo(&#039;*** Show the content of the archive recursively&#039;);
zipfile.forEach(function(folderItem, arcfile)
{
	if ( ! folderItem.IsFolder ) {
		WScript.Echo(folderItem.Path, folderItem.Size);
		return;
	}

	WScript.Echo(folderItem.Path);

	var items = folderItem.GetFolder.Items();
	var len = items.Count;
	for (var i = 0; i &lt; len; i++) {
		var g = items.Item(i);
		arguments.callee(g, arcfile);
	}
});</code></pre></div><p>В этом примере открывается архивный файл test.zip и выводится рекурсивно список всех файлов и каталогов, содержащихся в архиве. Дополнительно, для каждого файла в архиве выводится его реальный размер. Метод вызывает заданную функцию для каждого объекта в архиве. В функцию передаются два аргумента: <br />1. объект File или Folder, находящийся в архиве<br />2. объект Folder, виртуальная папка проводника, реализующая доступ к архиву</p><p>***</p><p><strong>Исходный код библиотеки</strong><br />Здесь помещена последняя редакция библиотеки (удалена шапка с примерами, которые уже были рассмотрены чуть ранее). Актуальная версия доступна по адресу <a href="http://code.google.com/p/jsxt/source/browse/trunk/js/win32/ZipFile.js">http://code.google.com/p/jsxt/source/br … ZipFile.js</a><br /></p><div class="codebox"><pre><code>

/**
 * Creates new object to work with archives. It can accept the same 
 * arguments as the ZipFile#open method. For details see the description 
 * of the method. 
 *
 * @return	ZipFile
 * @acess	public
 * @see		ZipFile#open
 */
function ZipFile()
{
	if ( arguments.length == 0 ) {
		return;
	}
	this.open.apply(this, arguments);
};

(function()
{

var fso = new ActiveXObject(&#039;Scripting.FileSystemObject&#039;);
var shellApp = new ActiveXObject(&quot;Shell.Application&quot;);

/**
 * Opens a specified file. Creates a file if it was pointed. The name is 
 * mandatory argument passing the name of the existing archive or the name 
 * of the file that will be created. In the last case additional arguments 
 * are needed. 
 *
 * @param	String	Mandatory. String expression that identifies the 
 * 			existing file or the file to create. 
 * @param	Boolean	Optional. Boolean value that indicates whether a 
 * 			new file can be created 
 * @param	Boolean	Optional. Boolean value that indicates whether you 
 * 			can overwrite an existing file. It depends on the 
 * 			create argument is true. 
 *
 * @return	void
 * @acess	public
 */
ZipFile.prototype.open = function(name, create, overwrite)
{
	if ( create ) {
		var zipFile = fso.CreateTextFile(name, !! overwrite, 0);
		zipFile.Write(&#039;PK\05\06&#039; + new Array(19).join(&#039;\0&#039;)); // 18 zeros
		zipFile.Close();
	}

	this.name = fso.GetFile(name).Path;
	this.file = shellApp.NameSpace(this.name);
};

/**
 * Fake method. It allows a script to flush data to a disk to complete 
 * processing. In fact, it just suspends script execution for a specified 
 * length of time. 
 *
 * @param	Number	Integer value indicating the interval (in 
 * 			milliseconds) you want the script process to be 
 * 			inactive. 
 *
 * @return	void
 * @access	public
 */
ZipFile.prototype.flush = function(timeout)
{
	timeout = Math.max(Number(timeout) || 0, 100);
	WScript.Sleep(timeout);
};

/**
 * Executes a provided function once for each item from within a archive. 
 * Once called it allows to perform any action with items from an archive.
 * The callback function is invoked with two arguments:
 * -- The FolderItem argument refers to the real object (file or folder) 
 *    within the archive 
 * -- The Folder object that refers to the archive file
 *
 * @param	Function	Mandatory. A function that will be called 
 * 				for each item in the archive
 *
 * @return	void
 * @access	piblic
 */
ZipFile.prototype.forEach = function(func)
{
	if ( typeof func != &#039;function&#039; ) {
		throw new TypeError();
	}

	var arcfile = this.file;
	var items = arcfile.Items();

	for (var e = new Enumerator(items); ! e.atEnd(); e.moveNext()) {
		var folderItem = e.item();
		func(folderItem, arcfile);
	}
};

/**
 * Executes a provided function once for each item before input it to the 
 * archive. Once called it allows to perform any action with items. The 
 * callback function is invoked with two arguments: 
 * -- The FolderItem argument refers to the real object (file or folder) 
 *    before putting it into the archive 
 * -- The Folder object that refers to the archive file
 *
 * @param	Array/String	Mandatory. The list of items taht will be 
 * 				put into the archive. 
 * @param	Function	Mandatory. A function that will be called 
 * 				before an item will be put into the 
 * 				archive 
 *
 * @return	void
 * @access	piblic
 */
ZipFile.prototype.forInput = function(input, func)
{
	if ( typeof func != &#039;function&#039; ) {
		throw new TypeError();
	}

	var arcfile = this.file;

	if ( typeof input == &#039;string&#039; ) {
		input = [input];
	}

	for (var i = 0; i &lt; input.length; i++) {
		var p = input[i];
		if ( ! p ) {
			continue;
		}

		var folderItem = null;
		if ( fso.FileExists(p) ) {
			folderItem = fso.GetFile(p);
		} else if ( fso.FolderExists(p) ) {
			folderItem = fso.GetFolder(p);
		}

		func(folderItem, arcfile);
	}
};

})();</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (Rumata)]]></author>
			<pubDate>Thu, 19 Apr 2012 01:08:38 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=59543#p59543</guid>
		</item>
	</channel>
</rss>
