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 addFile 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 compressedSize 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 addFile method. For example, calling the method as addFile(example.png,~/Images/example.png) 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 readTextFile and readJsonFile 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 extractFile method for specific files, as well as an extractAll 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
}
}