什麼是 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 24 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 11 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 20 21 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 5 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 17 18 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 ; }
喜歡這篇文章,請幫忙拍拍手喔 🤣