微信小程序 - 文件工具类 fileUtil.js

微信小程序 - 文件工具类 fileUtil.js

分享代码片段

https://developers.weixin.qq.com/s/1BNIfims7ENH

函数列表

函数名 简介
chooseMedia 选择媒体文件
chooseFile 从聊天中选择文件
ls 获取目录结构
unlinkSync 删除文件(同步版)
clearDir 清空目录:包含所有子目录和文件
clearDirSync 清空目录(同步版):包含所有子目录和文件
clearFilesSync 清空目录下的文件(同步版)(只删除文件)
isExist 判断文件或目录是否存在
mkdir 创建目录路(同步版)(如果目录不存在就创建)
rmdirSync 删除目录
addSuffixNumber 为文件名添加编号后缀
padNumber 高位补零
getFileInfo 解析文件路径返回:{路径、全名、文件名、扩展名}
readFileSync 读取本地文件内容。单个文件大小上限为100M。
writeFileSync 写文件

代码

javascript 复制代码
/**
 * 微信小程序 - 文件工具类
 * 对一些常用的功能进行了封装。
 * 笑虾 20230901
 */
 
const fs = wx.getFileSystemManager();

/**
 * 选择媒体文件
 * @param {object} options 
 */
function chooseMedia(options = {}){
  const defaultOptions = { count: 9, mediaType: ['image']};
  return wx.chooseMedia({...defaultOptions, ...options});
}

/**
 * 从聊天中选择文件
 * @param {number} _count 
 */
function chooseFile(_count){
  return wx.chooseMessageFile({ count: _count })
  .then( res => {
    //  res 内容: {
    //     "errMsg":"chooseMessageFile:ok",
    //     "tempFiles":[
    //       {
    //         "name":"spineboy.zip",
    //         "size":273679,
    //         "time":1692946544,
    //         "path":"http://tmp/eZhBTvHhtCEN1328314d91c79395dce640b2f2aba2e7.zip",
    //         "type":"file"
    //       }
    //     ]
    //   }
    if(res.errMsg === "chooseMessageFile:ok"){
      return res.tempFiles;
    }else{
      return [];
    }
  });
}

/**
 * 获取目录结构
 * @param {string} rootPath 
 */
function ls(rootPath) {  
  // 检查目录是否存在  
  if(!isExist(rootPath)){
    return [];
  }
  let list = fs.statSync(`${rootPath}`, true);

  if(Array.isArray(list) == false && list.isDirectory()) {
    return [];
  }

  // 返回一个对象包含 dirPath 目录下的文件和子目录:{'file':[], 'dir': []}
  return list.map(df => {
    df.type = df.stats.isFile() ? 'file' : 'dir';
    return df;
  }).reduce((result, item) => {
    item.path = `${rootPath}/${item.path}`;
    result[item.type].push(item);
    return result;
  }, {'file':[], 'dir': []});
}

/**
 * 删除文件(同步版)
 * @param {string} filePath 文件路径
 */
function unlinkSync(filePath){
  if(isExist(filePath) == false){
    console.log(`文件不存在:${filePath}`)
    return;
  }
  try {
    const res = fs.unlinkSync(filePath);
    console.log(res)
  } catch(e) {
    console.error(e)
  }
}

/**
 * 清空目录:包含所有子目录和文件
 * @param {string} rootPath 要清空的目录
 * @param {*} saveSelf      是否删除自己。为 false 则只清空其实的子目录和文件,但保留自己
 */
function clearDir(rootPath, saveSelf=true) {  
  // 检查目录是否存在  
  if(!isExist(rootPath)){
    return;
  }

  // 获取:文件与子目录
  let group = ls(rootPath);
  if(Array.isArray(group.file) == false){ // 如果file属性不是一个数组,说明没查到东西。是个空文件夹。
    return;
  }

  // 删除所有文件
  let p = group.file.map(f => {
    return new Promise((resolve, reject) => {
      fs.unlink({
        filePath: f.path,
        success: res => resolve(res),
        fail: err => reject(err)
      })
    });
  });

  // 删除全部文件后,再执行删除目录。
  Promise.all(p).then(res => {
    fs.rmdir({
      dirPath: `${rootPath}`,
      recursive: true,
      success: res => console.log(res),
      fail: err => console.error(err),
    });
  });
  // 上面是直接递归删除整个目录,包括自己。这里判断一下,如果需要保留根目录,就再创建一下。
  if(saveSelf){
    mkdir(rootPath);
  }
}

/**
 * 清空目录(同步版):包含所有子目录和文件
 * @param {string} rootPath 要清空的目录
 * @param {*} saveSelf      是否删除自己。为 false 则只清空其实的子目录和文件,但保留自己
 */
function clearDirSync(rootPath, saveSelf=true) {  
  // 检查目录是否存在  
  if(!isExist(rootPath)){
    return;
  }

  // 获取:文件与子目录
  let group = ls(rootPath);
  if(Array.isArray(group.file) == false){ // 如果file属性不是一个数组,说明没查到东西。是个空文件夹。
    return;
  }

  // 删除所有文件
  group.file.map(f => fs.unlinkSync(f.path));
  // 递归删除全部目录。
  fs.rmdirSync(rootPath, true);

  // 上面是直接递归删除整个目录,包括自己。这里判断一下,如果需要保留根目录,就再创建一下。
  if(saveSelf){
    mkdir(rootPath);
  }
}

/**
 * 清空目录下的文件(同步版)(只删除文件)
 * @param {string} rootPath 要清空的目录
 * @returns 被删除的文件列表
 */
function clearFilesSync(rootPath) {  
  try {
    // 获取目录下的文件列表
    const files = fs.readdirSync(rootPath);
    // 删除所有文件
    files.forEach(path => fs.unlinkSync(`${rootPath}/${path}`));
    return files;
  } catch (error) {
    console.error(error);
  }
}

/**
 * 判断文件或目录是否存在
 * @param {string} path 文件或目录路径
 */
function isExist(path){
  try {
    fs.accessSync(path);
    return true;
  } catch (err) {
    console.log(`文件或目录不存在:${err.message}`);
    return false;
  }
}
/**
 * 创建目录路
 * 如果目录不存在就创建。
 * @param {string} dirPath 文件夹路径
 * @param {boolean} recursive 如果上级目录不存在,是否自动创建。默认:是
 */
function mkdir(path, recursive = true){
  if(isExist(path) == false){                       // 判断目录是否存在
    fs.mkdirSync(path, recursive);                  // 如果没有就创建
  }
}

/**
 * 删除目录
 * @param {string} path 要删除的目录路径 (本地路径) 
 * @param {boolean} recursive 是否递归删除目录。如果为 true,则删除该目录和该目录下的所有子目录以及文件
 */
function rmdirSync(path, recursive=false){
  if(isExist(path)){                       // 判断目录是否存在
    fs.rmdirSync(path, recursive);            // 如果存在就删除
  }
}

/**
 * 为文件名添加编号后缀
 * @param {*} fileName      原文件名
 * @param {*} suffixNumber  编号
 * @param {*} suffixLen     编号位数
 */
function addSuffixNumber(fileName, suffixNumber, suffixLen) {
    // 获取文件名与扩展名
    let extension = '';  
    let index = fileName.lastIndexOf('.');  
    if (index !== -1) {  
        extension = fileName.substring(index);  
        fileName = fileName.substring(0, index);  
    }  
    // 计算后缀序号的位数  
    let suffixLength = Math.floor(Math.log10(suffixLen)) + 1;
    // 对后缀编号进行高位补零  
    let paddedSuffixNumber = String(suffixNumber).padStart(suffixLength, '0');  
    // 返回新的文件名  
    return `${fileName}_${paddedSuffixNumber}${extension}`;  
}

/**
 * 高位补零
 * @param {*} num       需要补零的序号
 * @param {*} count     序号所在序列中,的总数。用于计算要补几位
 * @param {*} suffixStr 自定补啥字符
 */
function padNumber(num, count=10, suffixStr='0') {
  // 计算后缀序号的位数  
  let suffixLength = Math.floor(Math.log10(count)) + 1;
  // 对后缀编号进行高位补零  
  return String(num).padStart(suffixLength, suffixStr);  
}

/**
 * 解析文件路径返回:{路径、全名、文件名、扩展名}
 * @param {*} filePath 文件路径
 */
function getFileInfo(filePath) {  
  // 获取文件夹路径  
  const folderPath = filePath.substring(0, filePath.lastIndexOf('/') + 1);
  // 获取文件名  
  const fileName = filePath.substring(folderPath.length, filePath.lastIndexOf('.'));
  // 获取扩展名  
  const fileExtension = filePath.substring(filePath.lastIndexOf('.') + 1);
  return {  
    path: folderPath,  
    fullName: `${fileName}.${fileExtension}`,
    name: fileName,  
    extension: fileExtension  
  };  
}

/**
 * 读取本地文件内容。单个文件大小上限为100M。
 * @param {*} filePath 文件路径。要读取的文件的路径 (本地路径)
 * @param {*} encoding 指定读取文件的字符编码,如果不传 encoding,则以 ArrayBuffer 格式读取文件的二进制内容
 * @param {*} position 默认从0开始读取。左闭右开区间 [position, position+length)。有效范围:[0, fileLength - 1]。单位:byte
 * @param {*} length   指定文件的长度,如果不指定,则读到文件末尾。有效范围:[1, fileLength]。单位:byte
 */
function readFileSync(filePath, encoding='', position=0, length) {  
  return fs.readFileSync(filePath, encoding, position, length);
}

/**
 * 写文件
 * @param {*} filePath 文件路径。要写入的文件路径 (本地路径)
 * @param {*} data 要写入的文本或二进制数据
 * @param {*} encoding 指定写入文件的字符编码。默认 binary
 */
function writeFileSync(filePath, data, encoding='binary') {  
  fs.writeFileSync(filePath, data, encoding);
}

module.exports = {
  chooseMedia,
  chooseFile,
  ls,
  unlinkSync,
  clearDir,
  clearDirSync,
  clearFilesSync,
  isExist,
  mkdir,
  rmdirSync,
  addSuffixNumber,
  padNumber,
  readFileSync,
  writeFileSync
};

参考资料

FileSystemManager wx.getFileSystemManager()

相关推荐
Eiceblue2 分钟前
React 项目实战:用 JavaScript 合并多个本地 Excel 文件
前端·javascript·react.js·excel
深蓝AI1 小时前
TypeScript 7.0 原生编译器实战:8—12 倍提速,迁移前的 7 个检查
javascript
mayaairi1 小时前
JS BOM完全指南(二):事件轮询、三大尺寸家族与浏览器对象详解
开发语言·javascript·ecmascript
Fluxart.ai3 小时前
商品多角度图怎么做?Flux Art 从白底图到规格图、包装图的 10 步教程
开发语言·前端·javascript
维双云3 小时前
2026微信小程序开店用哪个平台?长期稳定运营的系统选择方法
微信小程序·小程序
程序员小八7774 小时前
后端开发初学TypeScript
前端·javascript·typescript
辛迪聊物业数字化4 小时前
【智能楼宇系统有什么用?赋能园区高效 节能 安全】
经验分享·安全·微信小程序·php
单线程121385 小时前
从案例分析 Vue3 Tokenizer 源码
前端·javascript·vue.js
GIS数据转换器5 小时前
智慧林草“一张图“平台
java·大数据·服务器·前端·javascript·数据库·人工智能
烂蜻蜓6 小时前
Flask入门教程(十):静态文件——CSS、JS与图片的正确管理方式
javascript·css·flask