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 属性提供的未压缩大小进行比较。
通过将文件在归档中预计位置的完整路径提供至 addFile 方法,作为第二个参数,您即可在 ZIP 归档中创建子文件夹。例如,调用 addFile(example.png,~/Images/example.png) 方法将把文件添加到归档文件中的 Images 子文件夹,同时创建尚不存在的文件夹。
读取归档内的文件
AppFramework 可用于读取归档内文件,而不提取文件的方法有限;只能使用 ZipReader 组件的 readTextFile 和 readJsonFile 属性相应读取文本文件和 JSON 文件的内容。
该代码示例修改自上述创建归档的示例,会从所选 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
}
}