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 属性提供的未压缩大小进行比较。

通过将文件在归档中预计位置的完整路径提供至 addFile 方法,作为第二个参数,您即可在 ZIP 归档中创建子文件夹。例如,调用 addFile(example.png,~/Images/example.png) 方法将把文件添加到归档文件中的 Images 子文件夹,同时创建尚不存在的文件夹。

读取归档内的文件

AppFramework 可用于读取归档内文件,而不提取文件的方法有限;只能使用 ZipReader 组件的 readTextFilereadJsonFile 属性相应读取文本文件和 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
    }
}