您好,登錄后才能下訂單哦!
本篇內容介紹了“Tauri打開本地文件錯誤怎么解決”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
需求很簡單,就是打開本地圖片進行展示,同時還要能拿到圖片在本地的絕對路徑。
展示圖片
拿到絕對路徑
最先想到辦法,當然是使用input
元素,這是前端讀取本地文件的常規方案,而且我曾經使用electron
實現過一樣的功能,大致就是:
<input type="file" id="file-selector" />
document.getElementById("file-selector").addEventListener('change', e => { const files = e.target.files files.forEach(file => { const url = URL.createObjectURL(file) const path = file.path }) })
但遺憾的是,Tauri
的File對象并沒有實現path
這個屬性。
出于安全考慮,瀏覽器并沒有提供File對象的絕對路徑,path
是electron
自己提供的:electron/file-object.md at main · electron/electron (github.com)。
隨后,盡管想了各種辦法,比如引入file-selector之類的,但最終的結論是:input拿不到文件的絕對路徑。
我在心里吐槽“Tauri
果然是不如electron
”之后,我決定去Github上搜一下issue,不出所料,不只我一個人遇到這個問題:
Getting a real path of file type input · Issue #87
這里面給出了一個拿到文件絕對路徑的辦法,那就是使用Dialog
首先在tauri.conf.json
添加配置:
"allowlist": { "dialog": { "all": false, "open": true } }
然后
import { open } from "@tauri/api/dialog" async handler(){ let file = await open() }
open
方法會像input file一樣打開一個文件選擇框,返回文件的絕對路徑。
如果想一次選擇多個文件,可以添加選項:
let files = await open({ multiple: true })
實際嘗試發現,這樣確實能拿到文件的絕對路徑,但也只有絕對路徑。
于是我就陷入了困境:通過input可以展示圖片,但拿不到絕對路徑,而dialog可以拿到絕對路徑,卻無法顯示圖片,因為前端無法直接通過一個本地的絕對路徑來展示圖片。
怎么辦呢?
于是,我開始考慮使用Tauri
提供的fs API,利用絕對路徑來讀取文件內容,然后再轉換成Blob對象。
配置tauri.conf.json
"allowlist": { "dialog": { "all": false, "open": true }, "fs": { "all": false, "readFile": true, } }
讀取文件并轉換:
import { readBinaryFile } from '@tauri-apps/api/fs'; import { open } from "@tauri/api/dialog" async handler(){ // 打開文件獲取絕對路徑 let files = await open({ multiple: true }) files.forEach(async filePath => { // 讀取二進制文件 const contents = await readBinaryFile(filePath) // 轉換為blob對象,然后轉換為url const blob = new Blob([contents]) const url = URL.createObjectURL(blob) }) }
但是,正如我預期的那樣,這么做有嚴重的性能問題。
經簡單測試,打開100張圖片(每張400kb左右)需要好幾秒鐘才能完成,打開500張圖片更是花了約20秒才處理完畢。
而如果使用input file,500張圖片只要一兩秒就能搞定。
所以,雖然功能上已經沒有問題,但性能問題無法忽視,看來還需要找找別的辦法。
經過一整天的摸索,我最終找到了Tauri
提供這個函數:convertFileSrc,可以將一個絕對路徑轉換為類似于URL.createObjectURL
那樣的URL。
值得一提的是,這個函數和最常用的 invoke
處于同一個模塊內,而且在Tauri的文檔中,convertFileSrc
甚至位于invoke
之前,但我卻一直沒有注意到它,一方面是因為,之前從沒有想過要使用絕對路徑來轉換URL,因為純前端是做不到這一點的;另一方面,由于思維慣性,前端打開本地文件往往都是用的input file,遇到這個問題我一直想的是如何從input事件著手,沒有去仔細看文檔……這就是所謂的燈下黑嗎
首先,配置tauri.conf.json
{ "allowlist": { "dialog": { "all": true, "open": true }, "protocol": { "all": false, "asset": true, "assetScope": [ "$PICTURE" ] } }, "security": { "csp": "default-src 'self'; img-src 'self'; asset: https://asset.localhost" } }
然后
import { convertFileSrc } from '@tauri-apps/api/tauri' import { open } from "@tauri/api/dialog" async handler(){ let files = await open({ multiple: true }) files.forEach(filePath => { const url = convertFileSrc(filePath) }) }
速度和HTML原生的input file差不多,雖然拿不到文件大小之類的信息,但至少我最需要的兩個需求可以實現了,只要有了絕對路徑,文件大小之類的可以交給Rust。
“Tauri打開本地文件錯誤怎么解決”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。