在此步骤中,您将学习以下内容:
- 如何获取对外部文件系统中文件的引用。
- 如何写入文件系统。
完成此步骤预计用时: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 仅包含导出到磁盘按钮上的点击监听器和
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
添加到应用窗口,以便 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 上的探索 FileSystem API;或者
请参阅 MDN 上的 FileEntry docs
。
保留 FileEntry 对象
高级:FileEntry
对象无法无限期保留。您的应用需要询问用户
来选择一个文件。如果您的应用因运行时而被强制重启
崩溃或更新,restoreEntry() 是一个恢复 FileEntry
的选项。
如果您愿意,可以尝试保存 retainEntry() 返回的 ID 并在应用中恢复该 ID。
重启。(提示:在后台页面中为 onRestarted
事件添加监听器。)
启动完成的待办事项应用
您已完成第 6 步!重新加载应用并添加一些待办事项。点击导出到磁盘以导出您的 改为.txt 文件
了解详情
如需详细了解此步骤中引入的一些 API,请参阅:
- 使用 Chrome Filesystem API ↑
- 声明权限 ↑
- chrome.storage.local.get() ↑
- chrome.fileSystem.chooseEntry() ↑
- chrome.fileSystem.getDisplayPath() ↑
- chrome.fileSystem.restoreEntry() ↑
- chrome.fileSystem.retainEntry() ↑
准备好继续下一步了吗?转到第 7 步 - 发布应用 »