ZIP-архивы

ZIP-архивы можно использовать для сжатия нескольких файлов в один пакет. Размер архивного файла гораздо меньше, чем исходных файлов, которые были сжаты, позволяя использовать пространство хранения более эффективно; кроме того, передавать один файл архива гораздо проще.

Создание и добавление файлов в ZIP-архив

Для создания ZIP-архива используйте метод компонента ZipWriter addFile для записи в архив конкретного файла со свойством path, описывающим местоположение ZIP-архива. Файл ZIP не существует, пока в него не добавлен хотя бы один файл, то есть архив создается уже с файлом или файлами внутри него. В этом примере кода используется диалоговое окно файла для добавления свойства path.

ZipReader {
    id: zipReader
}
ZipWriter {
    id: zipWriter
}
Grid {
    columns: 2
    spacing: 5
    anchors {
        left: parent.left
        right: parent.right
        top: titleText.bottom
        bottom: parent.bottom
        margins: 10
    }
    Button {
        text: "Path"
        onClicked: {
            fileDialog.open();
        }
    }
    Text {
        text: zipReader.path
    }
    Label {
        text: "Folders"
    }
    ComboBox {
        model: zipReader.folderNames
    }
    Label {
        text: "Files"
    }
    ComboBox {
        model: zipReader.fileNames
    }
    Button {
        text: "Add File"
        onClicked: {
            addFileDialog.open();
        }
    }
}
FileDialog {
    id: fileDialog
    title: "Choose a ZIP archive"
    selectExisting: false
    selectMultiple: false
    nameFilters: [ "ZIP archives (*.zip)", "All files (*)" ]
    onAccepted: {
        console.log("ZIP archive url: " + fileDialog.fileUrl)
        zipReader.path = AppFramework.urlInfo(fileDialog.fileUrl).localFile;
        zipWriter.path = zipReader.path;
    }
}
FileDialog {
    id: addFileDialog
    title: "Choose a file to archive"
    selectExisting: true
    selectMultiple: false
    nameFilters: [ "All files (*)" ]
    onAccepted: {
        console.log("ZIP archive url: " + addFileDialog.fileUrl)
        var path = AppFramework.urlInfo(addFileDialog.fileUrl).localFile;
        zipWriter.addFile(path);
        zipReader.refresh();
    }
}

Степень сжатия файла при добавлении в ZIP-архив, главным образом, зависит от типа этого файла. Текстовые файлы, которые используются для создания большинства компонентов AppFramework, сжимаются менее чем на 10 процентов от их исходного размера, так как формат этих файлов уже подразумевает высокую степень сжатия (например, файлы JPG для фото), и при архивировании сжатие минимально. Если вам важно знать степень сжатия файла в архиве, в компоненте ZipFileInfo содержится свойство compressedSize, которое возвращает размер файла внутри архива для сравнения и исходным размером несжатого файла, информация о котором содержится в свойстве size.

В ZIP-архиве можно создать подпапки, указав полный путь к месту, где файлы будут в архиве, в виде второго параметра к методу addFile. Например, вызов метода addFile(example.png,~/Images/example.png) добавит файл в архив внутри подпапки Images, при этом папка будет создана, если она не существует.

Чтение файлов из архива

Возможности AppFramework по чтению файлов непосредственно в архиве, без извлечения, очень ограничены; можно прочитать только содержание текстовых файлов и файлов JSON, используя свойства readTextFile и readJsonFile компонента ZipReader соответственно.

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

Button {
    text: "Path"
    onClicked: {
        archiveFileDialog.open();
    }
}
FileDialog {
    id: archiveFileDialog
    title: "Choose a ZIP archive"
    selectExisting: true
    selectMultiple: false
    nameFilters: [ "ZIP archives (*.zip)", "All files (*)" ]
    onAccepted: {
        console.log("ZIP archive url: " + archiveFileDialog.fileUrl)
        zipReader.path = AppFramework.urlInfo(archiveFileDialog.fileUrl).localFile;
        textFileContents.text = zipReader.readTextFile("TestFile.txt")
    }
}
ZipReader {
    id: zipReader
}
TextArea {
    id: textFileContents
}

Для чтения и использования остальных файлов ZIP-архива, файлы необходимо предварительно извлечь. Для этого ZipReader предлагает метод extractFile для конкретных файлов, а также метод extractAll для всего архива.

// Instantiates ZipReader, points path property to preexisting archive
ZipReader {
    id: zipReader
    path: "~/ArcGIS/Example App/Zip archive.zip"
    onError: {
        console.log("Error extracting ", fileName)
    }
    // Creates progress notifications when extraction is ongoing
    onProgress: {
        if(percent == 0)
            resultArea.text +="\n" + "Extracting Next item" +"\n\n"
            resultArea.text +=  ("Extracted- %1 file %2 % at %3 ").arg(fileName).arg(percent).arg(outputFileName) + "\n"
    }
    onCompleted: {
        resultArea.text +=  "\n Extract completed"
    }
}
Column {
    spacing: 10
    Text {
        text: zipReader.path
    }
    Button { //Extracts contents of ZIP archive into a set folder inside app's files
        text: "Click to Extract ZIP File"
        onClicked: {
            zipReader.extractAll("~/Output Folder")
        }
    }
    TextArea { //Text area where progress notifications will display
        id: resultArea
        width: app.width
        height: app.height
    }
}