Статьи

Извлечение стратегического архива с помощью Distill

Возможно, вы создаете приложение, которое зависит от архивов; Например, вам постоянно приходится скачивать архивы и извлекать из них файлы. Существует множество библиотек, которые могут помочь вам извлечь файлы из архива, и новый игрок в городе, способный выполнять эту работу, — Distill .

С помощью Distill вы можете легко извлечь архив в указанный каталог. Вы также можете отдать несколько архивов Distill и позволить ему выбрать наиболее оптимальный в соответствии со стратегией, которую вы определяете сами. Давайте углубимся в код, чтобы увидеть, чего мы можем достичь с помощью Distill.

Если вы хотите следовать, вы можете взглянуть на этот репозиторий Github, чтобы проверить код.

Настроить

Прежде чем мы сможем начать использовать Distill, обратите внимание, что на момент написания он поддерживает только системы на основе Unix. Причина этого заключается в том, что Distill использует инструменты командной строки, которые в настоящее время доступны только в системах на основе Unix.

В разделе поддерживаемых форматов вы можете четко увидеть, какие команды должны быть доступны в командной строке.

Чтобы добавить Distill в ваш проект, мы ожидаем, что у вас уже есть проект, запущенный с composer. Вы можете установить Distill, запустив:

composer require raulfraile/distill:~0.6.*

использование

Прежде всего, нам нужно архивировать файлы в нескольких разных форматах. Если вы скачали вышеупомянутый репозиторий, у вас будет 3 архива в каталоге files

Мы начнем с создания класса экстрактора. Мы создаем файл в src/SitePoint/ExtractorExtractor

 namespace SitePoint\Extractor;

use Distill\Distill;

/**
 * Class to extract archived files
 */
class Extractor
{    
    /**
     * @var Distill
     */
    private $distiller;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->distiller = new Distill();
    }
}

Мы начнем с создания метода для извлечения всех файлов из архива. Нам нужен фактический файл для этого и каталог для извлечения. Сам метод пока ничего особенного не делает. Вы можете расширить его позже с проверками, если файл действителен, например.

Метод должен выглядеть примерно так.

 /**
 * Extract files into directory
 *
 * @param string $fromFile
 * @param string $toDirectory
 */
public function extract($fromFile, $toDirectory)
{
    $this->distiller->extract($fromFile, $toDirectory);
}

Переменная fromFile Переменная toDirectory Дистилль сделает все остальное за вас.

Извлечение архива — это то, что могут делать несколько библиотек. Что особенного в Distill, так это то, что вы можете добавить массив файлов, в которых Distill сделает наиболее оптимальный выбор. Чтобы создать этот метод, мы сначала добавим некоторые константы в класс.

 /**
 * Minimum size strategy
 */
const MINIMUM_SIZE = "\Distill\Strategy\MinimumSize";

/**
 * Uncompression speed strategy
 */
const UNCOMPRESSION_SPEED = "\Distill\Strategy\UncompressionSpeed";

/**
 * Random strategy
 */
const RANDOM = "\Distill\Strategy\Random";

При поставке в Distill нескольких архивных файлов, Distill выберет, какой архив подходит вам лучше всего, исходя из выбранной стратегии. При стратегии minimum size Вы можете использовать эту стратегию, например, когда хотите сэкономить пропускную способность.

Когда скорость важна для вас, вы должны использовать стратегию uncompression speed Distill проверит, какой файл он может извлечь быстрее всего, и будет использовать этот файл.

Если вам не важно, какой файл он использует, вы можете использовать random

Так как мы также хотим извлечь файл немедленно, мы можем повторно использовать уже созданный метод извлечения для этого. Вот как может выглядеть ваш метод.

 /**
 * Choose one of the files within the array and extract it to the given directory
 *
 * @param array  $fromFiles
 * @param string $toDirectory
 * @param string $preferredStrategy
 */
public function chooseAndExtract(array $fromFiles, $toDirectory, $preferredStrategy = self::MINIMUM_SIZE)
{
    $preferredFile = $this->distiller
        ->getChooser()
        ->setStrategy(new $preferredStrategy())
        ->setFiles($fromFiles)
        ->getPreferredFile();

    self::extract($preferredFile, $toDirectory);
}

Основываясь на массиве файлов, которые получает Distill, он автоматически выбирает, какой файл является предпочтительным. Этот файл будет затем извлечен в выбранный вами каталог. Если вы последовали соответствующим образом, теперь у вас должен быть класс, который выглядит следующим образом.

 namespace SitePoint\Extractor;

use Distill\Distill;

/**
 * Class to extract archived files
 */
class Extractor
{
    /**
     * Minimum size strategy
     */
    const MINIMUM_SIZE = "\Distill\Strategy\MinimumSize";

    /**
     * Uncompression speed strategy
     */
    const UNCOMPRESSION_SPEED = "\Distill\Strategy\UncompressionSpeed";

    /**
     * Random strategy
     */
    const RANDOM = "\Distill\Strategy\Random";

    /**
     * @var Distill
     */
    private $distiller;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->distiller = new Distill();
    }

    /**
     * Extract files into directory
     *
     * @param string $fromFile
     * @param string $toDirectory
     */
    public function extract($fromFile, $toDirectory)
    {
        $this->distiller->extract($fromFile, $toDirectory);
    }

    /**
     * Choose one of the files within the array and extract it to the given directory
     *
     * @param array  $fromFiles
     * @param string $toDirectory
     * @param string $preferredStrategy
     */
    public function chooseAndExtract(array $fromFiles, $toDirectory, $preferredStrategy = self::MINIMUM_SIZE)
    {
        $preferredFile = $this->distiller
            ->getChooser()
            ->setStrategy(new $preferredStrategy())
            ->setFiles($fromFiles)
            ->getPreferredFile();

        self::extract($preferredFile, $toDirectory);
    }
}

Давайте попробуем, если класс работает правильно. Мы создаем файл index.php

 require_once __DIR__ . '/vendor/autoload.php';

$files = array(
    'files/sitepoint.zip',
    'files/sitepoint.tar.gz',
    'files/sitepoint.tar'
);

$extractor = new \SitePoint\Extractor\Extractor();
$extractor->extract(current($files), 'files/extracted/simple');
$extractor->chooseAndExtract($files, 'files/extracted/advanced', \SitePoint\Extractor\Extractor::RANDOM);

Если мы запустим php index.php

Вывод

Distill — это очень специфическая библиотека, и может показаться, что ей не хватает функций по сравнению с другими инструментами манипулирования архивами. Но в этой нише она фокусируется, она превосходит. Если вы ищете облегченный экстрактор, который может помочь вам сэкономить пропускную способность и / или время, Distill может быть той библиотекой, которую вы ищете. Может быть, вы даже можете объединить его с компрессором и сделать отличный гибридный пакет для функций манипулирования архивом вашего приложения? Попробуйте и дайте нам знать, как это сработало для вас.