1
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
## 1.0.1(2025-08-17)
|
||||
* 鸿蒙原生支持。
|
||||
## 1.0.0(2024-12-18)
|
||||
* 对指定目录/文件进行压缩并返回压缩文件路径以便上传和管理.
|
||||
@@ -0,0 +1,100 @@
|
||||
{
|
||||
"id": "x-zip-s",
|
||||
"displayName": "应用内文件压缩和解压zip",
|
||||
"version": "1.0.1",
|
||||
"description": "可以对你的应用文件数据进行压缩目录和解压zip文件",
|
||||
"keywords": [
|
||||
"zip,压缩,解压"
|
||||
],
|
||||
"repository": "",
|
||||
"engines": {
|
||||
"HBuilderX": "^3.6.8",
|
||||
"uni-app": "",
|
||||
"uni-app-x": "^4.75"
|
||||
},
|
||||
"dcloudext": {
|
||||
"type": "uts",
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "10.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": "",
|
||||
"darkmode": "x",
|
||||
"i18n": "x",
|
||||
"widescreen": "√"
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "√",
|
||||
"aliyun": "√",
|
||||
"alipay": "√"
|
||||
},
|
||||
"client": {
|
||||
"uni-app": {
|
||||
"vue": {
|
||||
"vue2": "-",
|
||||
"vue3": "-"
|
||||
},
|
||||
"web": {
|
||||
"safari": "-",
|
||||
"chrome": "-"
|
||||
},
|
||||
"app": {
|
||||
"vue": "-",
|
||||
"nvue": "-",
|
||||
"android": "-",
|
||||
"ios": "-",
|
||||
"harmony": "-"
|
||||
},
|
||||
"mp": {
|
||||
"weixin": "-",
|
||||
"alipay": "-",
|
||||
"toutiao": "-",
|
||||
"baidu": "-",
|
||||
"kuaishou": "-",
|
||||
"jd": "-",
|
||||
"harmony": "-",
|
||||
"qq": "-",
|
||||
"lark": "-"
|
||||
},
|
||||
"quickapp": {
|
||||
"huawei": "-",
|
||||
"union": "-"
|
||||
}
|
||||
},
|
||||
"uni-app-x": {
|
||||
"web": {
|
||||
"safari": "-",
|
||||
"chrome": "-"
|
||||
},
|
||||
"app": {
|
||||
"android": {
|
||||
"extVersion": "",
|
||||
"minVersion": "21"
|
||||
},
|
||||
"ios": "√",
|
||||
"harmony": "√"
|
||||
},
|
||||
"mp": {
|
||||
"weixin": "x"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
# x-zip-s
|
||||
### 开发文档
|
||||
|
||||
压缩和解压插件,目前仅支持zip格式.主要可以对app的数据缓存文件进行压缩,然后上传到服务器使用的场景.
|
||||
|
||||
### 兼容性
|
||||
|
||||
| Harmony | IOS | Android | WEB | 小程序 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 支持 | 支持 | 支持 | x | x |
|
||||
|
||||
|
||||
### 使用
|
||||
|
||||
如果是安卓请务必打自定义基座,如果ios:你在mac环境下配置好了环境无需打包本地编译,如果win开发ios需要打包基座。
|
||||
|
||||
|
||||
```ts
|
||||
|
||||
import { addZip,unZip,addZipAndSaveDisk } from "@/uni_modules/x-zip-s"
|
||||
/**
|
||||
* 压缩文件
|
||||
* target,需要压缩的目录,如:uni.env.CACHE_PATH+'/dir/'
|
||||
* filepath,添加的压缩的文件路径及名称如:uni.env.CACHE_PATH + 'test.zip'
|
||||
*/
|
||||
addZip(target,filepath,(pathfile:string)=>{
|
||||
//压缩成功后返回路径
|
||||
console.log(pathfile)
|
||||
})
|
||||
/**
|
||||
* 解压文件
|
||||
* path:待解压的文件路径
|
||||
* target:解压至目标目录
|
||||
*/
|
||||
unZip(path,target)
|
||||
|
||||
/**
|
||||
* ios,鸿蒙 Next专用函数,压缩成功后会直接打开系统手机
|
||||
* 存储器,提示保存到icloud或者手机文件夹,你可以通过mac电脑同步保存.
|
||||
*/
|
||||
// #ifdef APP-IOS || APP-HARMONY
|
||||
addZipAndSaveDisk(target,filepath,(pathfile:string)=>{
|
||||
console.log(pathfile)
|
||||
})
|
||||
// #endif
|
||||
|
||||
```
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"minSdkVersion": "21",
|
||||
"dependencies":[
|
||||
"org.apache.commons:commons-compress:1.27.1"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
|
||||
import ArchiveEntry from "org.apache.commons.compress.archivers.ArchiveEntry";
|
||||
import ArchiveStreamFactory from "org.apache.commons.compress.archivers.ArchiveStreamFactory";
|
||||
import ZipArchiveInputStream from "org.apache.commons.compress.archivers.zip.ZipArchiveInputStream";
|
||||
import ZipArchiveEntry from "org.apache.commons.compress.archivers.zip.ZipArchiveEntry";
|
||||
import ZipArchiveOutputStream from "org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream";
|
||||
import IOUtils from "org.apache.commons.compress.utils.IOUtils";
|
||||
import File from "java.io.File";
|
||||
import FileOutputStream from "java.io.FileOutputStream";
|
||||
import IOException from "java.io.IOException";
|
||||
import InputStream from "java.io.InputStream";
|
||||
import ArchiveStreamProvider from 'org.apache.commons.compress.archivers.ArchiveStreamProvider'
|
||||
import URL from 'java.net.URL';
|
||||
import FileInputStream from 'java.io.FileInputStream';
|
||||
import BufferedInputStream from 'java.io.BufferedInputStream';
|
||||
import BufferedOutputStream from 'java.io.BufferedOutputStream';
|
||||
// import { FileManager } from "ZIPFoundation"
|
||||
import ArchiveInputStream from 'org.apache.commons.compress.archivers.ArchiveInputStream';
|
||||
import Deflater from 'java.util.zip.Deflater';
|
||||
|
||||
function compressDirectoryToZipFile(rootDir : File,sourceDir : File,zipOut : ZipArchiveOutputStream) {
|
||||
// 获取目录下的所有文件和子目录
|
||||
let listfiles = sourceDir.listFiles();
|
||||
if(listfiles==null) return;
|
||||
listfiles.forEach(file => {
|
||||
let relativePath = file.absolutePath.substring(rootDir.absolutePath.length + 1)
|
||||
if (file.isDirectory) {
|
||||
// 如果是目录,创建一个目录条目(以 "/" 结尾)
|
||||
let dirEntry = new ZipArchiveEntry(relativePath + "/")
|
||||
zipOut.putArchiveEntry(dirEntry)
|
||||
zipOut.closeArchiveEntry()
|
||||
// 递归压缩子目录
|
||||
compressDirectoryToZipFile(rootDir, file, zipOut)
|
||||
} else {
|
||||
// 如果是文件,创建文件条目并写入内容
|
||||
let fileEntry = new ZipArchiveEntry(relativePath)
|
||||
zipOut.putArchiveEntry(fileEntry)
|
||||
let bis = BufferedInputStream(FileInputStream(file));
|
||||
let buffer = ByteArray(1024)
|
||||
var len : Int = bis.read(buffer)
|
||||
while (len != -1) {
|
||||
zipOut.write(buffer, 0, len)
|
||||
len = bis.read(buffer)
|
||||
}
|
||||
zipOut.closeArchiveEntry()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
export const addZip = (path : string, target : string,callback:(path:string)=>void) => {
|
||||
let sourceDirectory = new File(UTSAndroid.convert2AbsFullPath(path))
|
||||
// 检查源目录是否存在
|
||||
if (!sourceDirectory.exists() || !sourceDirectory.isDirectory) {
|
||||
throw IllegalArgumentException("Source directory does not exist or is not a directory")
|
||||
}
|
||||
let fos = new FileOutputStream(UTSAndroid.convert2AbsFullPath(target))
|
||||
let zipOut = ZipArchiveOutputStream(fos)
|
||||
// 设置压缩方法
|
||||
zipOut.setMethod(ZipArchiveOutputStream.DEFLATED)
|
||||
zipOut.setLevel(Deflater.BEST_SPEED)
|
||||
// 压缩目录
|
||||
compressDirectoryToZipFile(sourceDirectory, sourceDirectory, zipOut)
|
||||
callback(UTSAndroid.convert2AbsFullPath(target))
|
||||
}
|
||||
export const addZipAndSaveDisk = (path : string, filename : string, callback : (path : string) => void) => {
|
||||
|
||||
}
|
||||
|
||||
|
||||
export const unZip = (path : string, target : string) => {
|
||||
let failepath = UTSAndroid.convert2AbsFullPath(path)
|
||||
let targetpath = UTSAndroid.convert2AbsFullPath(target)
|
||||
let outputDir = new File(targetpath);
|
||||
if (!outputDir.exists()) {
|
||||
outputDir.mkdirs();
|
||||
}
|
||||
|
||||
let fis = new FileInputStream(failepath);
|
||||
let zipIn = new ArchiveStreamFactory().createArchiveInputStream(ArchiveStreamFactory.ZIP, fis) as ZipArchiveInputStream
|
||||
let entry = zipIn.getNextEntry();
|
||||
|
||||
while (entry != null) {
|
||||
console.log(entry.getName())
|
||||
let outputFile = new File(outputDir, entry.getName())
|
||||
if (entry.isDirectory()) {
|
||||
outputFile.mkdirs()
|
||||
} else {
|
||||
outputFile.parentFile?.mkdirs()
|
||||
let bos = new BufferedOutputStream(FileOutputStream(outputFile))
|
||||
let buffer = new ByteArray(1024)
|
||||
var len : Int = zipIn.read(buffer)
|
||||
while (len != -1) {
|
||||
bos.write(buffer, 0, len);
|
||||
len = zipIn.read(buffer)
|
||||
}
|
||||
}
|
||||
entry = zipIn.getNextEntry();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"x_zip_s": "./lib/x_zip_s.har"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { x_createTestFile, x_addZip, x_unZip,x_addZipAndSaveDisk } from "x_zip_s"
|
||||
|
||||
/**
|
||||
* 测试函数
|
||||
*/
|
||||
export const testZipFile = ()=>{
|
||||
x_createTestFile(UTSHarmony.getCurrentWindow()!.getUIContext())
|
||||
}
|
||||
|
||||
/**
|
||||
* 压缩文件或者文件夹
|
||||
* @description 必须是沙盒路径
|
||||
* @param path 待压缩的文件夹 x/x
|
||||
* @param target 压缩后存放的文件路径如x/x.zip
|
||||
*/
|
||||
export const addZip = (path : string, target : string,callback:(path:string)=>void) => {
|
||||
x_addZip(path,target,callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* 压缩文件至系统手机目录
|
||||
* @description 必须是沙盒路径
|
||||
* @param path 文件路径如:x.zip
|
||||
* @param filename 保存的文件名
|
||||
*/
|
||||
export const addZipAndSaveDisk = (path : string, filename:string,callback:(path:string)=>void) => {
|
||||
x_addZipAndSaveDisk(UTSHarmony.getCurrentWindow()!.getUIContext(),path,filename,callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* 解压缩文件
|
||||
* @description 必须是沙盒路径
|
||||
* @param path 文件路径如:x/x.zip
|
||||
* @param target 解压至目录文件夹 x/x
|
||||
*/
|
||||
export const unZip = (path : string, target : string) => {
|
||||
x_unZip(path,target)
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPITypes</key>
|
||||
<array/>
|
||||
<key>NSPrivacyCollectedDataTypes</key>
|
||||
<array/>
|
||||
<key>NSPrivacyTracking</key>
|
||||
<false/>
|
||||
<key>NSPrivacyTrackingDomains</key>
|
||||
<array/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"deploymentTarget": "12",
|
||||
"dependencies-pods": [
|
||||
{
|
||||
"name": "ZIPFoundation",
|
||||
"version": "0.9.19"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
import { Archive } from "ZIPFoundation"
|
||||
import { URL, FileManager, URLResourceKey, CharacterSet } from 'Foundation';
|
||||
import { UIDocumentBrowserAction, UIDocumentPickerViewController, UIDocumentPickerMode, UIViewController } from 'UIKit';
|
||||
|
||||
/**
|
||||
* 压缩文件或者文件夹
|
||||
* @description 必须是沙盒路径
|
||||
* @param path 待压缩的文件夹 x/x
|
||||
* @param target 压缩后存放的文件路径如x/x.zip
|
||||
*/
|
||||
export const addZip = (path : string, target : string,callback:(path:string)=>void) => {
|
||||
|
||||
let fileManager = FileManager.default
|
||||
let archiveURL = new URL(fileURLWithPath = UTSiOS.convert2AbsFullPath(target))
|
||||
|
||||
console.log(archiveURL.path, '----')
|
||||
let socurl = new URL(fileURLWithPath = UTSiOS.convert2AbsFullPath(path))
|
||||
|
||||
let archive = UTSiOS.try(new Archive(url = archiveURL, accessMode = Archive.AccessMode.create), "?")
|
||||
if (archive == null) {
|
||||
console.log("archiveURL:fail", archive)
|
||||
callback('')
|
||||
return;
|
||||
}
|
||||
|
||||
let enumerator : FileManager.DirectoryEnumerator = fileManager.enumerator(at = socurl, includingPropertiesForKeys = [URLResourceKey.isRegularFileKey, URLResourceKey.isDirectoryKey])!
|
||||
let fileURL : URL | null = enumerator.nextObject() as URL | null
|
||||
let i = 1
|
||||
while (fileURL != null) {
|
||||
let str = fileURL!.path.replace(socurl.path, '') as String
|
||||
str = str.replace('/private', '') as String
|
||||
let relativePath = str.trimmingCharacters(in = new CharacterSet(charactersIn = "/"))
|
||||
if (!fileManager.fileExists(atPath = fileURL!.path)) {
|
||||
fileURL = enumerator.nextObject() as URL | null
|
||||
continue;
|
||||
}
|
||||
let parentstr = fileURL!.path.substring(0, fileURL!.path.lastIndexOf("/"))
|
||||
let parentUrl = new URL(fileURLWithPath = parentstr.replace('/private', ''))
|
||||
UTSiOS.try(archive!.addEntry(with = relativePath, fileURL = fileURL!), '?')
|
||||
fileURL = enumerator.nextObject() as URL | null
|
||||
i += 1;
|
||||
}
|
||||
console.log("zip:ok", archiveURL.path)
|
||||
callback(archiveURL.path)
|
||||
}
|
||||
|
||||
/**
|
||||
* 压缩文件至系统手机目录
|
||||
* @description 必须是沙盒路径
|
||||
* @param path 文件路径如:x/x.zip
|
||||
* @param filename 保存的文件名
|
||||
*/
|
||||
export const addZipAndSaveDisk = (path : string, filename:string,callback:(path:string)=>void) => {
|
||||
let fileManager = FileManager.default
|
||||
let downloadsDirectory = FileManager.default.temporaryDirectory
|
||||
let archiveURL = downloadsDirectory as URL
|
||||
archiveURL.appendPathComponent(filename)
|
||||
console.log(archiveURL.path, '----')
|
||||
let socurl = new URL(fileURLWithPath = UTSiOS.convert2AbsFullPath(path))
|
||||
let archive = UTSiOS.try(new Archive(url = archiveURL, accessMode = Archive.AccessMode.create), "?")
|
||||
if (archive == null) {
|
||||
console.log("archiveURL:fail", archive)
|
||||
callback('')
|
||||
return;
|
||||
}
|
||||
|
||||
let enumerator : FileManager.DirectoryEnumerator = fileManager.enumerator(at = socurl, includingPropertiesForKeys = [URLResourceKey.isRegularFileKey, URLResourceKey.isDirectoryKey])!
|
||||
let fileURL : URL | null = enumerator.nextObject() as URL | null
|
||||
let i = 1
|
||||
while (fileURL != null) {
|
||||
let str = fileURL!.path.replace(socurl.path, '') as String
|
||||
str = str.replace('/private', '') as String
|
||||
|
||||
let relativePath = str.trimmingCharacters(in = new CharacterSet(charactersIn = "/"))
|
||||
if (!fileManager.fileExists(atPath = fileURL!.path)) {
|
||||
fileURL = enumerator.nextObject() as URL | null
|
||||
continue;
|
||||
}
|
||||
let parentstr = fileURL!.path.substring(0, fileURL!.path.lastIndexOf("/"))
|
||||
let parentUrl = new URL(fileURLWithPath = parentstr.replace('/private', ''))
|
||||
|
||||
// relativePath = relativePath.substring((relativePath.lastIndexOf("/")+1).toInt())
|
||||
UTSiOS.try(archive!.addEntry(with = relativePath, fileURL = fileURL!), '?')
|
||||
console.log("序号:", i, str)
|
||||
fileURL = enumerator.nextObject() as URL | null
|
||||
|
||||
i += 1;
|
||||
|
||||
}
|
||||
console.log("zip:ok", archiveURL.path)
|
||||
let documentPicker = new UIDocumentPickerViewController(url = archiveURL, in = UIDocumentPickerMode.exportToService)
|
||||
let rootview = UTSiOS.getCurrentViewController() as UIViewController
|
||||
rootview.present(documentPicker, animated = true, completion = nil)
|
||||
callback(archiveURL.path)
|
||||
}
|
||||
|
||||
/**
|
||||
* 解压缩文件
|
||||
* @description 必须是沙盒路径
|
||||
* @param path 文件路径如:x/x.zip
|
||||
* @param target 解压至目录文件夹 x/x
|
||||
*/
|
||||
export const unZip = (path : string, target : string) => {
|
||||
let fileManager = FileManager.default
|
||||
let targetpath = new URL(fileURLWithPath = UTSiOS.convert2AbsFullPath(target))
|
||||
let zippathfile = new URL(fileURLWithPath = UTSiOS.convert2AbsFullPath(path))
|
||||
let result = UTSiOS.try(fileManager.unzipItem(at = zippathfile, to = targetpath), "?")
|
||||
if (result == null) {
|
||||
console.log("unzip:fail", result)
|
||||
return;
|
||||
}
|
||||
console.log("unzip:ok")
|
||||
}
|
||||
Reference in New Issue
Block a user