Archiwa ZIP

Archiwa ZIP mogą być używane do kompresowania pewnej liczby plików w jeden pakiet. Rozmiar pliku takiego archiwum jest mniejszy niż plików składowych, co pozwala na bardziej efektywne przechowywanie plików, a samo archiwum może być przesyłane jako pojedynczy plik.

Tworzenie archiwum ZIP i dodawanie do niego plików

Aby utworzyć archiwum ZIP, należy za pomocą metody addFile komponentu ZipWriter zapisać w nim określony plik z właściwością path opisującą lokalizację archiwum ZIP. Plik ZIP zostanie utworzony dopiero po dodaniu do niego przynajmniej jednego pliku. W tym momencie zostanie utworzone archiwum, które będzie zawierać już plik. W tym przykładowym kodzie do przekazania informacji do właściwości path użyto okien dialogowych pliku.

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();
    }
}

Stopień skompresowania pliku po dodaniu do archiwum ZIP zależy całkowicie od typu pliku. Pliki tekstowe, które są używane i tworzone przez pewną liczbę komponentów modułu AppFramework, mogą zostać skompresowane do wartości wynoszącej mniej niż 10 procent rozmiaru pierwotnego, podczas gdy rozmiar plików o formatach już wysoce skompresowanych (np. plików JPG w przypadku zdjęć) nie zostanie znacząco zmniejszony. Jeśli znajomość rozmiaru skompresowanego archiwum jest istotna, za pomocą właściwości compressedSize komponentu ZipFileInfo można zwrócić rozmiar pliku znajdującego się w archiwum w celu porównania z nieskompresowanym rozmiarem podanym przez właściwość size.

Podfoldery w archiwum ZIP można utworzyć, podając pełną ścieżkę do lokalizacji plików w archiwum jako drugi parametr metody addFile. Na przykład wywołanie metody addFile(example.png,~/Images/example.png) spowoduje dodanie pliku do archiwum wewnątrz podfolderu Images. Ten folder zostanie utworzony, jeśli jeszcze nie istnieje.

Odczytywanie plików z archiwum

Moduł AppFramework ma ograniczone możliwości czytania z archiwum bez jego rozpakowania. Może on tylko odczytywać zawartość plików tekstowych i plików JSON odpowiednio przy użyciu właściwości readTextFile i readJsonFile komponentu ZipReader.

Poniższy przykładowy kod będący modyfikacją powyższego przykładu ilustrującego tworzenie archiwum wyświetla zawartość konkretnego pliku tekstowego z wybranego archiwum ZIP. Jeśli ten plik tekstowy jest pusty lub nie istnieje, obszar tekstu będzie pusty.

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
}

Aby można było odczytywać inne pliki zawarte w archiwum ZIP i ich używać, należy najpierw rozpakować je z archiwum. Do realizacji tego celu komponent ZipReader udostępnia metodę extractFile dla konkretnych plików, jak również metodę extractAll dla całego archiwum.

// 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
    }
}