在這個步驟中,您將瞭解:
- 如何取得外部檔案系統中的檔案參照。
- 如何寫入檔案系統。
預計完成這個步驟的時間:20 分鐘。
如要預覽這個步驟中要完成的內容,請向下跳到本頁底部 ↓。
匯出待辦事項
這個步驟會將匯出按鈕新增至應用程式。點選後,目前的待辦事項會儲存至使用者選取的文字檔案中。如果檔案存在,系統會取代該檔案。否則,系統會建立新檔案。
更新權限
您可以要求檔案系統權限做為唯讀存取權字串,或要求包含其他屬性的物件。例如:
// Read only
"permissions": ["fileSystem"]
// Read and write
"permissions": [{"fileSystem": ["write"]}]
// Read, write, autocomplate previous input, and select folder directories instead of files
"permissions": [{"fileSystem": ["write", "retainEntries", "directory"]}]
您必須具備讀取及寫入權限。在 manifest.json 中,要求 {fileSystem: [ "write" ] }
權限:
"permissions": [
"storage",
"alarms",
"notifications",
"webview",
"<all_urls>",
{ "fileSystem": ["write"] }
],
更新 HTML 檢視模式
在 index.html 中新增「匯出至磁碟」按鈕和 div
,讓應用程式顯示狀態訊息:
<footer id="info">
<button id="toggleAlarm">Activate alarm</button>
<button id="exportToDisk">Export to disk</button>
<div id="status"></div>
...
</footer>
另外,在 index.html 中載入 export.js 指令碼:
...
<script src="js/alarms.js"></script>
<script src="js/export.js"></script>
建立匯出指令碼
使用下方程式碼,建立名為 export.js 的新 JavaScript 檔案。將這個檔案儲存在 js 資料夾中。
(function() {
var dbName = 'todos-vanillajs';
var savedFileEntry, fileDisplayPath;
function getTodosAsText(callback) {
}
function exportToFileEntry(fileEntry) {
}
function doExportToDisk() {
}
document.getElementById('exportToDisk').addEventListener('click', doExportToDisk);
})();
目前,export.js 只包含「Export to 磁碟」按鈕上的點擊事件監聽器,以及 getTodosAsText()
、exportToFileEntry
和 doExportToDisk()
的虛設常式。
以文字形式取得待辦事項
更新 getTodosAsText()
,使其從 chrome.storage.local
讀取待辦事項,並產生以文字表示的待辦事項:
function getTodosAsText(callback) {
chrome.storage.local.get(dbName, function(storedData) {
var text = '';
if ( storedData[dbName].todos ) {
storedData[dbName].todos.forEach(function(todo) {
text += '- ';
if ( todo.completed ) {
text += '[DONE] ';
}
text += todo.title;
text += '\n';
}, '');
}
callback(text);
}.bind(this));
}
選擇檔案
使用 chrome.fileSystem.chooseEntry()
更新 doExportToDisk()
,讓使用者能夠選擇檔案:
function doExportToDisk() {
if (savedFileEntry) {
exportToFileEntry(savedFileEntry);
} else {
chrome.fileSystem.chooseEntry( {
type: 'saveFile',
suggestedName: 'todos.txt',
accepts: [ { description: 'Text files (*.txt)',
extensions: ['txt']} ],
acceptsAllTypes: true
}, exportToFileEntry);
}
}
chrome.fileSystem.chooseEntry()
的第一個參數是選項的物件。第二個參數是回呼方法。
如果已有已儲存的 FileEntry
,請在呼叫 exportToFileEntry()
時改用這個已儲存 FileEntry
。檔案參照存在於代表 FileEntry
物件的生命週期內。這個範例會將 FileEntry
連結至應用程式視窗,這樣一來,只要應用程式視窗保持開啟,JavaScript 程式碼就可以直接寫入所選檔案,而不進行任何使用者互動。
使用 FileEntry 將待辦事項項目寫入磁碟
更新 exportToFileEntry()
,透過 FileEntry
Web API 將待辦事項儲存為文字:
function exportToFileEntry(fileEntry) {
savedFileEntry = fileEntry;
var status = document.getElementById('status');
// Use this to get a file path appropriate for displaying
chrome.fileSystem.getDisplayPath(fileEntry, function(path) {
fileDisplayPath = path;
status.innerText = 'Exporting to '+path;
});
getTodosAsText( function(contents) {
fileEntry.createWriter(function(fileWriter) {
var truncated = false;
var blob = new Blob([contents]);
fileWriter.onwriteend = function(e) {
if (!truncated) {
truncated = true;
// You need to explicitly set the file size to truncate
// any content that might have been there before
this.truncate(blob.size);
return;
}
status.innerText = 'Export to '+fileDisplayPath+' completed';
};
fileWriter.onerror = function(e) {
status.innerText = 'Export failed: '+e.toString();
};
fileWriter.write(blob);
});
});
}
chrome.fileSystem.getDisplayPath()
會取得可顯示檔案路徑,並輸出至狀態 div
。
使用 fileEntry.createWriter()
建立 FileWriter
物件。接著,fileWriter.write()
就能將 Blob 寫入檔案系統。使用 fileWriter.onwriteend()
和 fileWriter.onerror()
更新狀態 div
。
若想進一步瞭解 FileEntry
,請參閱 HTML5Rocks 上的「探索檔案系統 API」,或是參閱 MDN 上的 FileEntry docs
。
保留 FileEntry 物件
進階:FileEntry
物件無法無限期保留。應用程式每次啟動時,都必須要求使用者選擇檔案。如果應用程式因執行階段當機或更新而強制重新啟動,restoreEntry() 是還原 FileEntry
的選項。
如有需要,您可以嘗試儲存 retainEntry() 傳回的 ID,並在應用程式重新啟動時還原 ID。(提示:將事件監聽器新增至背景頁面的 onRestarted
事件)。
啟動已完成的待辦事項應用程式
您已完成步驟 6!請重新載入應用程式,並新增待辦事項。按一下「Export toDisk」,將待辦事項匯出至 .txt 檔案。
瞭解詳情
如要進一步瞭解這個步驟介紹的某些 API,請參閱:
- 使用 Chrome Filesystem API ↑
- 宣告權限 ↑
- chrome.storage.local.get() ↑
- chrome.fileSystem.chooseEntry() ↑
- chrome.fileSystem.getDisplayPath() ↑
- chrome.fileSystem.restoreEntry() ↑
- chrome.fileSystem.retainEntry() ↑
準備好繼續進行下一步了嗎?請參閱步驟 7 - 發布應用程式 »