场景描述
在飞书小程序中,调用后端下载请求API下载文件,期望可以保存在手机本地
/飞书本地
/飞书临时目录
/飞书缓存
。
在网络上找的下载url,在后端还没给API之前测试用的:
http://files.cnblogs.com/MolbyHome/%E6%83%B3%E6%B3%95.rar
https://cdn.jsdelivr.net/gh/belaviyo/download-with/samples/sample.zip
文件系统
飞书小程序文件系统:https://open.feishu.cn/document/client-docs/gadget/-web-app-api/file/file-system
本地临时文件(以ttfile://temp开头):临时产生,小程序重启会被清空的文件。
本地用户文件(以ttfile://user开头):小程序通过接口把本地临时文件保存后产生的文件,每个小程序最多可存储 200MB。
选择手机本地文件系统的文件
用到的飞书小程序接口tt.filepicker
https://open.feishu.cn/document/client-docs/gadget/-web-app-api/file/filepicker
index.mpx
1 2 3 4 5 6 7 8 9 10 11
| <template> <view> <view class="container"> 打开手机本地文件系统 <button bindtap="openFileSystem">选择本地文件</button> </view> </view> </template>
<script lang="ts" src="./index.ts"> </script>
|
index.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| import mpx, { createPage } from "@mpxjs/core";
createPage({ data: { chooseFile: {}, },
methods: { openFileSystem() { console.log("打开文件系统,选择目标文件"); tt.filePicker({ maxNum: 10, pickerTitle: "Select a file", pickerConfirm: "Confirm", isSystem: false, success: (res) => { console.log(res); this.chooseFile = res.list[0]; }, fail: (res) => { console.log("filePicker fail:", res); }, }); }, }, });
|
下载并存储到Storage
请求下载时responseType为arraybuffer
,并且把文件存在Storage。
Storage简介
飞书官网:https://open.feishu.cn/document/client-docs/gadget/-web-app-api/cache/local-data-cache
小程序可以通过下面列出的API读取、写入、删除、清理本地缓存数据,与 LocalStorage 类似。
以「键值对」的形式设置本地缓存数据。
单个 key 允许存储的最大数据长度为 1MB,所有数据存储上限为 10MB,同时也受到用户设备存储空间、缓存清理等机制的限制,可能会导致信息丢失,因此请不要将重要数据存放在本地数据缓存。
setStorage
https://open.feishu.cn/document/client-docs/gadget/-web-app-api/cache/setstorage
1 2 3 4 5 6 7 8 9 10
| tt.setStorage({ key: "name", data: "小王", success(res) { console.log(JSON.stringify(res)); }, fail(res) { console.log(`setStorage fail: ${JSON.stringify(res)}`); } });
|
getStorage
https://open.feishu.cn/document/client-docs/gadget/-web-app-api/cache/getstorage
1 2 3 4 5 6 7 8 9
| tt.getStorage({ key: "name", success(res) { console.log(JSON.stringify(res)); }, fail(res) { console.log(`getStorage fail: ${JSON.stringify(res)}`); } });
|
更多接口请前往官网查看:
https://open.feishu.cn/document/client-docs/gadget/-web-app-api/cache/local-data-cache
- getStorage
- getStorageSync
- setStorage
- setStorageSync
- removeStorage
- removeStorageSync
- clearStorage
- clearStorageSync
- getStorageInfo
- getStorageInfoSync
下载文件存到Storage
用到的接口
tt.request
:
https://open.feishu.cn/document/client-docs/gadget/-web-app-api/network/initiating-request/request
tt.setStorage
:https://open.feishu.cn/document/client-docs/gadget/-web-app-api/cache/setstorage
tt.getStorage
:
https://open.feishu.cn/document/client-docs/gadget/-web-app-api/cache/getstorage
index.mpx
1 2 3 4 5 6 7 8 9 10 11 12
| <template> <view> <view class="container"> 下载文件,存到Storage (ArrayBuffer) <button bindtap="onDownloadStorage" style="background-color: #55efc4">下载文件</button> <button bindtap="readStorageFile">读取文件</button> </view> </view> </template>
<script lang="ts" src="./index.ts"> </script>
|
index.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| import mpx, { createPage } from "@mpxjs/core";
createPage({ methods: { onDownloadStorage() { const url = "https://freetestdata.com/wp-content/uploads/2021/09/Free_Test_Data_200KB_CSV-1.csv"; console.log("下载文件==="); tt.request({ url, responseType: "arraybuffer", success: (res) => { if (res.data) { console.log("download file success", res); const { data: arraybuffer } = res; const byteArr = new Uint8Array(arraybuffer); const arr = Array.from(byteArr); tt.setStorage({ key: 'test-file', data: arr, success: (res) => { console.log("setStorage success", res); }, fail: (res) => { console.error("setStorage fail", res); }, }); } }, fail: (err) => { console.error("download file fail", err); }, }); },
readStorageFile() { try { const result = tt.getStorageInfoSync(); console.log(`缓存信息 success: ${JSON.stringify(result)}`); } catch (error) { console.log(`缓存信息 fail: ${JSON.stringify(error)}`); }
tt.getStorage({ key: 'test-file', success: (res) => { console.log("getStorage success。",res); }, fail: (res) => { console.error("getStorage fail", res); }, }); }, }, });
|
飞书小程序下载文件并存到Storage
飞书小程序的Storage出现了缓存数据
下载到飞书本地临时目录
用到的飞书小程序接口tt.downloadFile
https://open.feishu.cn/document/client-docs/gadget/-web-app-api/network/download/downloadfile
index.mpx
1 2 3 4 5 6 7 8 9 10 11
| <template> <view> <view class="container"> 下载文件,存到临时目录 <button bindtap="onDownload" style="background-color: #55efc4">下载文件</button> </view> </view> </template>
<script lang="ts" src="./index.ts"> </script>
|
index.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import mpx, { createPage } from "@mpxjs/core"; createPage({ methods: { onDownload() { console.log("下载文件"); tt.downloadFile({ url: "http://files.cnblogs.com/MolbyHome/%E6%83%B3%E6%B3%95.rar", success: (res) => { console.log(res); }, fail: (res) => { console.log("downloadFile fail:", res); }, }); }, }, });
|
下载到飞书本地目录
注意:这里的本地目录是指飞书提供的隔离空间ttfile://user/
,不是手机系统本地目录。
方法:
飞书调用了downloadFile
API只能把文件下载到临时目录,不能直接飞书本地目录。
但是飞书可以把临时目录中的文件存到飞书本地目录tt.saveFile
。
tt.saveFile
: 该 API 会把临时文件移动到永久目录(目录最大200M),所以在调用成功后原文件路径将访问失败。
https://open.feishu.cn/document/client-docs/gadget/-web-app-api/file/file_system_manager/file_system_manager_save_file
因此,这里可以先把文件下载到临时目录,再把飞书临时目录中的文件存到飞书本地目录。
index.mpx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| <template> <view > <view style="content: ''; overflow: hidden;"></view>
<view style="color:blue;margin:30px"> <button bindtap="downloadFile">下载文件并保存到本地</button> <button bindtap="openDir">打印/user/所有文件列表</button> <button bindtap="clearDir">清空本地文件</button> </view> </view> </template>
<script> import { createPage } from '@mpxjs/core'
createPage({ methods: { openDir() { const fileSystemManager = tt.getFileSystemManager() try { const files = fileSystemManager.readdirSync('ttfile://user/') console.log('调用成功', files) } catch (err) { console.log('调用失败', err) } }, downloadFile() { wx.showLoading({ title: '下载中' }) const file = { name:'file-1.bin', size: 21.3, version: 'V3.1', date: '2023/01/21' },
console.log('下载升级文件') tt.downloadFile({ url: 'https://cdn.jsdelivr.net/gh/belaviyo/download-with/samples/sample.zip', success: (res) => { console.log('存到临时目录', res) const tempFilePath = res.tempFilePath
if (res.statusCode === 200 && tempFilePath) { tt.saveFile({ tempFilePath, filePath: 'ttfile://user/' + file.name, success: (res) => { console.log(`${JSON.stringify(res)}`) }, fail: (res) => { console.log(`saveFile fail: ${JSON.stringify(res)}`) } }) } wx.hideLoading() }, fail: (res) => { console.log('downloadFile fail:', res) wx.hideLoading() } }) }, removeSavedFile(fileList) { const fileSystemManager = tt.getFileSystemManager() fileList.forEach((file) => { console.log('准备删除文件:', JSON.stringify(file)) fileSystemManager.removeSavedFile({ filePath: file.filePath, success: (res) => { console.log(`${file.filePath} 删除成功`) }, fail: (res) => { console.error(`${file.filePath} 删除失败`, res.errMsg) } }) }) },
clearDir() { console.log('清空本地目录文件') const fileSystemManager = tt.getFileSystemManager() fileSystemManager.getSavedFileList({ success: (res) => { console.log('当前用户目录下的文件:', res) this.removeSavedFile(res.fileList) } }) } } }) </script>
<style lang="scss"> </style>
|
- 下载文件到临时目录
- 把文件从临时目录保存到本地目录
- 打印本地目录下所有文件的名称
- 清空本地文件目录(先遍历本地目录的文件,再去删除这些文件)