ZIP archives can be used to compress a number of files into a single package. This archive has a smaller file size than the files that comprise it, allowing the files to be stored more efficiently, and the archive itself can be transferred as a single file.
Create and add to a ZIP archive
To create a ZIP archive, use the ZipWriter component add
method to write a particular file to it, with the path
property describing the location of the ZIP archive. The ZIP file will not exist until at least one file has been added, at which point the archive will be created with the file already in it. This code sample uses file dialogs to inform the path
property.
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();
}
}
How much a file is compressed when added to a ZIP archive depends entirely on the file type. Text files, which are used and created by a number of AppFramework components, can be compressed to less than 10 percent of their original size, while files that are already in highly compressed formats (for example, JPG files for photos) won't considerably reduce in size. If the compressed size of the archive is important to know, the ZipFileInfo component has a compressed
property that returns the size of a file within the archive to compare to the uncompressed size provided by the size
property.
Subfolders can be created in the ZIP archive by providing the full file path of where the files will be in the archive as a second parameter to the add
method. For example, calling the method as add
will add the file into the archive inside an Images subfolder, creating one of it doesn't already exist.
Read files from archive
AppFramework has limited means to read from an archive without extracting it; it can only read the contents of text and JSON files using the read
and read
properties, respectively, of the ZipReader component.
This code sample, modified from the sample for creating an archive above, prints the contents of a specific text file from the selected ZIP archive. If this text file is empty or not present, the text area will be blank.
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
}
To read and use other files in the ZIP archive, the files must first be extracted from the archive. To do this, ZipReader provides an extract
method for specific files, as well as an extract
method for the entire archive.
// 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
}
}