tauri中加载本地文件图片或者下载网络文件图片后存储到本地,然后通过前端页面展示

有一个需求是需要将本地上传的文件或者网络下载的文件存储到本地,并展示在前端页面上的。其实如果只是加载本地文件,然后展示还是挺简单的,可以看我的文章:tauri程序加载本地图片或者文件在前端页面展示-CSDN博客

要想实现上述需求,需要三个步骤,配置相应的文件和文件夹访问权限,然后将文件存储到软件的相应目录中,再从目录中加载这个资源并展示。

配置访问权限

如果你需要通过弹窗选择加载本地文件,需要配置dialog权限,存储文件需要配置存储目录权限fs下面的scope和path权限,想要加载文件并在前端页面可以访问,需要配置资产协议访问权限protocol。其中scope是你要存储文件到哪个路径下,assetScope是你要访问哪些路径下的资源。

            "path": {
                "all": true
            },
            "fs": {
                "all": true,
                "readFile": true,
                "writeFile": true,
                "readDir": true,
                "copyFile": true,
                "createDir": true,
                "removeDir": true,
                "removeFile": true,
                "renameFile": true,
                "exists": true,
                "scope": ["$CACHE/PakePlus/*", "$APPDATA/*"]
            },
            "dialog": {
                "all": true,
                "ask": true,
                "confirm": true,
                "message": true,
                "open": true,
                "save": true
            },
            "protocol": {
                "all": true,
                "asset": true,
                "assetScope": ["$PICTURE", "$CACHE/*"]
            },

存储文件到本地

加载本地文件并存储到软件指定的文件夹中,这里需要读取到文件的内容,如果是图片文件,需要读为二进制内容,并进行存储。

import { writeBinaryFile, BaseDirectory } from '@tauri-apps/api/fs';
import { appDataDir } from '@tauri-apps/api/path';

const saveImageToAppData = async (filePath) => {
  // 读取原始图片文件
  const response = await fetch(filePath);
  const imageBlob = await response.blob();
  const imageArrayBuffer = await imageBlob.arrayBuffer();
  const imageData = new Uint8Array(imageArrayBuffer);

  // 获取应用数据目录
  const appDataDirPath = await appDataDir();

  // 拼接文件保存路径
  const fileName = filePath.split('/').pop();  // 获取原始文件名
  const savePath = `${appDataDirPath}/${fileName}`;

  // 将图片保存到应用数据目录
  await writeBinaryFile(savePath, imageData, { dir: BaseDirectory.AppData });

  console.log(`Image saved to: ${savePath}`);
  return savePath;
}

或者使用前端的input标签选中文件拿到base64编码的文件,然后转为ArrayBuffer再进行存储:

        <input
            id="open"
            type="file"
            name="filename"
            style="display: none"
            @change="changeFile"
        />



// iconInput change
const changeFile = (event: any) => {
    // get base64 content
    const file = event.target.files[0] // 获取文件
    console.log('file---', file)
    if (file) {
        appForm.icon = file.name
        console.log('file---', event.target.files)
        // appForm.icon = event.target.files.name
        const reader = new FileReader() // 创建FileReader对象
        reader.onload = function (e: any) {
            const base64String = e.target.result.split('base64,')[1] // 获取Base64编码
            console.log('base64String---', base64String) // 打印Base64编码内容
            // save image to datadir
            saveImage(file.name, base64String)
        }
        reader.readAsDataURL(file) // 将文件读取为Base64
    }
}



// save image file to datadir
const saveImage = async (fileName: string, base64: string) => {
    // base64 to arraybuffer
    const imageArrayBuffer = base64ToArrayBuffer(base64)
    // save file
    const imageData = new Uint8Array(imageArrayBuffer)
    // 获取应用数据目录
    const appDataPath = await resourceDir()
    console.log('appDataPath------', appDataPath)
    // 拼接文件保存路径
    const savePath = `${appDataPath}${fileName}`
    // 将图片保存到应用数据目录
    await writeBinaryFile(savePath, imageData, {
        dir: BaseDirectory.Cache,
    })
    console.log(`Image saved to: ${savePath}`)
    appForm.desc = savePath
    const filePath = await join(appDataPath, fileName)
    console.log('filePath---', filePath)
    const assetUrl = convertFileSrc(filePath)
    console.log('assetUrl---', assetUrl)
    localImagePath.value = assetUrl
}

// 将base64转换为ArrayBuffer
const base64ToArrayBuffer = (base64: string) => {
    // 创建一个新的 ArrayBuffer
    const binaryString = atob(base64)
    const len = binaryString.length
    const arrayBuffer = new ArrayBuffer(len)
    const uint8Array = new Uint8Array(arrayBuffer)
    // 将二进制字符串中的字符逐个存入 Uint8Array
    for (let i = 0; i < len; i++) {
        uint8Array[i] = binaryString.charCodeAt(i)
    }
    return arrayBuffer
}

加载文件为Url

读取保存的文件内容,并展示到页面上,需要拿到存储的路径,然后通过convertFileSrc这个api将文件路径转化为前端可以直接访问的文件:

    const filePath = await join(appDataPath, fileName)
    console.log('filePath---', filePath)
    const assetUrl = convertFileSrc(filePath)
    console.log('assetUrl---', assetUrl)
    localImagePath.value = assetUrl

如果是图片文件,直接将url设置进去就可以了。

报错解决

1.Unhandled Promise Rejection: The `Path` module is not enabled. You must enable one of its APIs in the allowlist.

这是因为没有开启path路径访问权限:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

1024小神

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值