uniapp微信小程序解压压缩包文件
解决:微信自带方法解压压缩包出现中文乱码问题
描述: 微信提供的unzip解压压缩包函数(18年到21年了, 还没改这个问题…) 出现中文乱码问题 , 遂改用jszip解压文件
在此记录一下本人小程序解压压缩包过程及方法
插件引用(注:自行下载jszip):
import jszip from '../../static/dist/jszip.min.js';
自定义变量:
export default {
data() {
return {
rootPath:wx.env.USER_DATA_PATH,//小程序中合法的可操作文件的根目录路径:
cachePath:wx.env.USER_DATA_PATH + "/unzip", // 存放解压文件的目录
}
},
onLoad(options){
let _this = this;
//判断是否存在解压文件的目录, 无则创建
_this.access();
},
onUnload() {
this.removeFile(); //移除目录文件
},
}
当前页面其他使用函数方法
说明: 以下函数方法为判断解压文件目录是否存在使用
//判断是否存在目录
access() {
let _this = this;
let fs = wx.getFileSystemManager();
fs.access({
path: _this.cachePath,
success: function(res) {
//res.errMsg == 'access:ok' 存在目录
console.log(res.errMsg);
},
fail: function(err) {
console.log(err.errMsg);
//不存在, 创建unzip目录
_this.mkdir();
}
});
},
//创建目录
mkdir(){
let _this = this;
let fs = wx.getFileSystemManager();
fs.mkdir({
dirPath: _this.cachePath,
recursive: true,
success: function(res) {
// res.errMsg == 'mkdir:ok' 创建目录成功
console.log(res.errMsg)
},
fail: function(err) {
console.log(err.errMsg)
}
});
},
//删除目录文件
removeFile(){
let _this = this;
let fs = wx.getFileSystemManager();
fs.readdir({
dirPath:_this.cachePath,
complete:function(res){
let PathArr = res.files;
fs.rmdir({
dirPath: _this.cachePath,
recursive:true,
complete:function(es){
console.log(es);
}
});
}
})
},
in_array:function(stringToSearch, arrayToSearch) {
for (var s = 0; s < arrayToSearch.length; s++) {
var thisEntry = arrayToSearch[s].toString();
if (thisEntry == stringToSearch) {
return true;
}
}
return false;
},
方案1
无所谓解压中文文件乱码问题
直接使用微信提供 unzip 方法 + 递归读取目录文件
uploadWxZip(){
wx.chooseMessageFile({
count: 1,
type:'file',
success: function (res) {
var Path = res.tempFiles[0].path;
var hostUrl = '';//你自己的文件上传服务器接口
uni.uploadFile({
url: hostUrl,
filePath: Path,
name: 'file',
success: res => {
//注: 此处作者项目原因稍有修改, 如有请求问题可改为自己熟悉的方法
var fileUrl = res.fileUrl;//上传成功返回的文件线上链接
var cacheUrl = _this.cachePath + '/' + fileName;//解压文件下载到本地的地址及文件名
this.doLocalUploadZip(fileUrl,cacheUrl);
}
});
}
});
},
//处理上传的压缩文件
doLocalUploadZip(fileUrl,cacheUrl){
let _this = this;
uni.showLoading({
title:'下载中'
});
//下载文件
wx.downloadFile({
url: fileUrl, //要下载的文件链接
filePath: cacheUrl, //下载到本地的文件路径
success: function (dres) {
uni.showLoading({
title:'解压中'
});
if (dres.statusCode === 200) { //成功
const fs = wx.getFileSystemManager();
fs.unzip({
zipFilePath: cacheUrl,//源文件路径,支持本地路径, 只可以是 zip 压缩文件
targetPath: _this.cachePath,//目标目录路径, 支持本地路径 注意:目录路径
success(tres) {
fs.readdir({
dirPath:_this.cachePath,
success(gres) {
uni.hideLoading();
var dirList = gres.files;//目录文件列表
dirList.forEach((dir_name,index)=>{
if(dir_name.indexOf('.',0) == -1){
//没有后缀当目录处理
_this.toDoDir(dir_name);//递归读取目录下的文件
}else{ //有文件后缀, 处理自己的逻辑
//TODO
}
});
},
fail(gres){ }
})
},
fail(tres) {}
});
}else{
uni.showToast({
title:'fail'
})
}
},
fail: function (res) {
uni.showToast({
title:'fail to'
})
}
});
},
//循环递归读取目录
toDoDir(dir_name){
let _this = this;
const fs = wx.getFileSystemManager();
var dirPath = _this.cachePath + '/'+ dir_name;
var digui = function (dirPath){
if(item.indexOf('.',0) == -1){ //当做目录dir
fs.readdir({
dirPath:dirPath,
complete:function(e){
// console.log(e);
//如果目录里还有目录
if(e.files){
e.files.forEach((name,index)=>{
if(name.indexOf('.',0) == -1){ //没有后缀当目录处理跳过
//目录前面要拼接之前的目录
var url = dir_name + '/' + name;
_this.toDoDir(url);
}else{
//TODO 有后缀的文件, 处理自己的业务逻辑
}
});
}
}
});
}
}
digui(dirPath);
},
方案2 ( 使用jszip )
可恶啊该死的中文乱码
使用jszip解压微信聊天记录中的压缩文件
附带安装下载:
npm install iconv-lite
safer-buffer 为iconv-lite使用
iconv-lite (必需:解决中文乱码问题)
//从微信聊天记录中获取压缩文件
wxUnZip(){
let _this = this;
wx.chooseMessageFile({
count: 1,
type:'file',
success: function (res) {
var Path = res.tempFiles[0].path;
var fileName = res.tempFiles[0].name;
var cacheUrl = _this.cachePath + '/' + fileName;
//try
const fs = wx.getFileSystemManager()
const binData = new Uint8Array(fs.readFileSync(Path))
var iconv = require('iconv-lite');//控制台中输入命令npm install iconv-lite
var zip = new jszip();
var i = 0;
zip.loadAsync(binData, {
decodeFileName: function (bytes) {
return iconv.decode(bytes, 'GBK');//解压中文必需参数
},
})
.then(function (loadedzip) {
uni.showLoading({ title:'解压中' });
// will be called, even if content is corrupted
var File = loadedzip.files;//获取到的所有文件列表 包括目录下
Object.keys(File).map((key)=>{
// File[key];//获得属性对应的值,可以进行其它处理
var item = File[key];
item.async('arraybuffer').then(function success(data){
if(!item.dir){ //不是目录
if(item.name.split('/').length != 0){
//目录下的文件 , item.name 中带文件夹目录名
//处理自己的业务逻辑
}else{
//压缩包根目录下的文件
// item.name 直接为文件名,处理业务逻辑
}
//将读取的文件数据保存到_this.cachePath(自己制定的目录)
fs.writeFile({
filePath:_this.cachePath + '/' + item.name,
data:data,
encoding: 'utf8',
complete(e) { }
});
}
}).then(function () {
uni.hideLoading();
});
});
}, function (e) {
// won't be called
});
}
});
}
方案3 ( 使用jszip )
解压本地的压缩文件
解压本地的与方案2相同, 仅多了一个步骤 就是将文件下载到微信可操作目录中
思路: 小程序中使用web-view , 在线上的html页面上传文件, 获取到文件线上路径之后跳转回小程序页面处理业务逻辑
onLoad(options){
let _this = this;
_this.access();
if(options.fileUrl){ //本地文件上传
let path = options.fileUrl;
var cacheUrl = _this.cachePath + '/' + name;
_this.doLocalUploadZip(path,cacheUrl);
}
},
//methods:{...}
//下方方法放入methods中
//处理上传的压缩文件
doLocalUploadZip(fileUrl,cacheUrl){
let _this = this;
uni.showLoading({ title:'处理中' });
//下载文件
wx.downloadFile({
url: fileUrl, //要下载的文件链接
filePath: cacheUrl, //下载地址
success: function (dres) {
if (dres.statusCode === 200) { //下载成功
const fs = wx.getFileSystemManager();
async function getZipFiles(zipUrl) {
uni.request({
url: zipUrl,
data: {},
method: "get",
responseType:'arraybuffer',
header: {'content-type': 'application/x-www-form-urlencoded'},
success: function(response) {
if (response.statusCode == 200) {
// console.log(response);
async function getZip(response){
uni.showLoading({ title:'解压中' });
var iconv = require('iconv-lite');
var new_zip = new jszip();
var zipData = await new_zip.loadAsync(response.data, {
decodeFileName: function (bytes) {
return iconv.decode(bytes, 'GBK');
},
});
//获取到的所有文件列表 包括目录下的文件
var File = zipData.files;
Object.keys(File).map((key)=>{ // File[key];//获得属性对应的值,可以进行其它处理
var item = File[key];
item.async('arraybuffer').then(function success(data){
if(!item.dir){ //不是目录
if(item.name.split('/').length != 0){ //是目录下的文件
}else{//压缩包根目录下的文件
}
//保存文件
fs.writeFile({
filePath:_this.cachePath + '/' + item.name,
data:data,
encoding: 'utf8',
complete(e) { }
});
}
}).then(function () {
uni.hideLoading();
});
});
}
getZip(response);
}
}
});
}
getZipFiles(fileUrl);
}
}
});
}