什麼是 File System Access API? 透過這個 File System Access API 就能透過程式操作本機上的檔案,舉例來說像是開啟或儲存檔案等,部分瀏覽器會需要給予相關的權限才能進行操作,除了開啟檔案 API 本身也提供了開啟目錄並列舉檔案列表的功能。
對 Progressive Web App 也會在某些情境需要可以存取和操作本機端的檔案,Google 的 Lab 提供了底下這個編輯器可以簡單試玩:
https://googlechromelabs.github.io/text-editor/
browser-fs-access library:https://github.com/GoogleChromeLabs/browser-fs-access
小編在幾年前剛學習 SPA 時也寫了個單頁筆記的應用,能夠快速的寫一些筆記,也附上原始碼和 Demo 連結。
原始碼: https://github.com/LinYenCheng/vue-note Demo 連結: https://linyencheng.github.io/vue-note/
透過瀏覽器讀取本機檔案 前幾年小編其實沒有使用過 File System Access API,所以顯然在操作上其實有兩種方式,那第一種是透過原生的 input
然後指定 type
為 file
就可以達到讀取的效果,第二種是透過 File System Access API 的 showOpenFilePicker()
。
直接在 html 中加入 <input type="file" id="fileInput">
並且簡單撰寫相關事件就能夠使用,程式碼如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 var fileInput = document .getElementById ("fileInput" );fileInput.addEventListener ("change" , function (e ) { var file = fileInput.files [0 ]; var textType = /text.*/ ; if (file.type .match (textType)) { var reader = new FileReader (); reader.onload = function (e ) { maindata.gridData = []; var objText = JSON .parse (reader.result .toString ()); objText.gridData .forEach (function (element, index ) { maindata.gridData .push (element); }); console .log (objText); }; reader.readAsText (file); } else { fileDisplayArea.innerText = "File not supported!" ; } });
使用 File System Access API 中的 showOpenFilePicker()
,最後取得的 File object 包含會一個 blob 可以透過以下的方法去取得相關的值: slice() stream() text() arrayBuffer() 1 2 3 4 5 6 7 8 9 10 let fileHandle;butOpenFile.addEventListener ("click" , async () => { [fileHandle] = await window .showOpenFilePicker ({ startIn : "pictures" , }); const file = await fileHandle.getFile (); const contents = await file.text (); textArea.value = contents; });
showOpenFilePicker
中的 startIn
提供的預設值是常見的幾個資料夾,能夠提供指定
desktop documents downloads music pictures videos 透過瀏覽器寫入本機檔案 操作上一樣會有兩種方式,第一種是產生出一個下載連結,將 Blob 檔案透過下載的方式寫入,第二種是透過 File System Access API 的 showSaveFilePicker()
。
將需要寫入的內容先產生成 Blob 然後產生成下載連結,最後透過程式去點擊連結去觸發開啟選擇寫入資料夾的視窗。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 function saveFile (text ) { var url = null ; var data = new Blob ([text], { type : "text/plain;" , }); if (url !== null ) { window .URL .revokeObjectURL (url); } url = window .URL .createObjectURL (data); var link = document .getElementById ("exportText" ); link.href = url; var filename = window .prompt ("輸入檔名" ) || "export" ; link.download = filename + ".txt" ; link.click (); }
透過 showSaveFilePicker()
開啟選擇寫入資料夾的視窗。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 const fileHandle = await self.showSaveFilePicker ({ suggestedName : "Untitled Text.txt" , types : [ { description : "Text documents" , accept : { "text/plain" : [".txt" ], }, }, ], }); async function writeFile (fileHandle, contents ) { const writable = await fileHandle.createWritable (); await writable.write (contents); await writable.close (); }
透過瀏覽器刪除本機檔案 這個之前小編就沒有試過其他方式,那透過 File System Access API 的 removeEntry()
是可以做到刪除檔案和刪除資料夾所有內容的效果。
1 2 3 4 await directoryHandle.removeEntry ("Abandoned Projects.txt" );await directoryHandle.removeEntry ("Old Stuff" , { recursive : true });
透過瀏覽器開啟目錄 File System Access API 的 showDirectoryPicker()
提供了我們操作目錄並列舉內容的功能。
1 2 3 4 const dirHandle = await window .showDirectoryPicker ();for await (const entry of dirHandle.values ()) { console .log (entry.kind , entry.name ); }
File System Access API 權限 部分瀏覽器環境還是會有權限的問題,所以偵測權限相關就變成也是要寫在程式碼裡,邏輯如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 async function verifyPermission (fileHandle, readWrite ) { const options = {}; if (readWrite) { options.mode = "readwrite" ; } if ((await fileHandle.queryPermission (options)) === "granted" ) { return true ; } if ((await fileHandle.requestPermission (options)) === "granted" ) { return true ; } return false ; }
喜歡這篇文章,請幫忙拍拍手喔 🤣