Storage API

应用开发几乎方方面面都涉及到发送或接收数据的一些元素。正在启动 您应使用 MVC 框架帮助您设计和实现应用,以便 与此数据的应用视图完全无关(请参阅MVC 架构)。

您还需要考虑应用离线时数据的处理方式(请参阅离线优先)。 本文档简要介绍了用于在本地发送、接收和保存数据的存储选项;该 本文档的其余部分介绍了如何使用 Chrome 的 File System API 和 Sync File System API(另请参阅 fileSystem APIsyncFileSystem API)。

存储选项

打包应用程序使用许多不同的机制来发送和接收数据。对于外部数据(资源、 网页),您需要了解内容安全政策 (CSP)。与 Chrome 类似 扩展程序,您可以使用跨源 XMLHttpRequests 与远程服务器进行通信。您 您还可以隔离外部页面,以确保应用的其余部分安全无虞(请参阅嵌入外部网页 页)。

在本地保存数据时,您可以使用 Chrome Storage API 保存少量字符串 和 IndexedDB 来保存结构化数据。借助 IndexedDB,您可以将 JavaScript 对象保留在 对象存储并使用存储的索引来查询数据(要了解详情,请参见 HTML5 Rock 的简单待办事项 列出教程)。对于所有其他类型的数据(例如二进制数据),请使用“文件系统和同步” 文件系统 API。

Chrome 的 Filesystem API 和 Sync Filesystem API 扩展了 HTML5 FileSystem API。通过 Chrome 的 Filesystem API,因此应用可以创建、读取、浏览和写入用户 本地文件系统例如,照片分享应用可以使用 Filesystem API 读取和写入任何 用户选择的照片。

借助 Chrome 的 Sync Filesystem API,应用可以保存和同步用户的 Google 云端硬盘中的数据, 确保不同的客户端可以提供相同的数据。例如,基于云计算的文本 编辑器应用可将新的文本文件自动同步到用户的 Google 云端硬盘账号。当 用户在新客户端中打开文本编辑器,Google 云端硬盘会将新文本文件推送到 文本编辑器。

使用 Chrome Filesystem API

正在添加文件系统权限

要使用 Chrome 的 File System API,您需将“fileSystem”对清单的权限 您可从用户处获取存储持久性数据的权限。

"permissions": [
  "...",
  "fileSystem"
]

用于选择文件的用户选项

用户希望以相同的方式选择文件。他们至少希望“选择” file'按钮和标准的文件选择器。如果您的应用大量使用文件处理功能,您还应该 实现拖放(请参阅下文,另请参阅原生 HTML5 拖放)。

获取 fileEntry 的路径

如需获取用户所选文件 fileEntry 的完整路径,请调用 getDisplayPath()

function displayPath(fileEntry) {
  chrome.fileSystem.getDisplayPath(fileEntry, function(path) {
    console.log(path)
  });
}

实现拖放

如果您需要实现拖放选择功能,可使用以下代码中的拖放文件控制器 (dnd.js) 不妨从 filesystem-access 示例入手。控制器会创建一个文件条目 从 DataTransferItem 添加。在此示例中,fileEntry 设置为第一个 已放下内容。

var dnd = new DnDFileController('body', function(data) {
  var fileEntry = data.items[0].webkitGetAsEntry();
  displayPath(fileEntry);
});

读取文件

以下代码会打开该文件(只读),并使用 FileReader 对象以文本形式读取该文件。如果 如果文件不存在,系统会抛出错误。

var chosenFileEntry = null;

chooseFileButton.addEventListener('click', function(e) {
  chrome.fileSystem.chooseEntry({type: 'openFile'}, function(readOnlyEntry) {

    readOnlyEntry.file(function(file) {
      var reader = new FileReader();

      reader.onerror = errorHandler;
      reader.onloadend = function(e) {
        console.log(e.target.result);
      };

      reader.readAsText(file);
    });
    });
});

写入文件

写入文件的两种常见用例是“保存”和“另存为”以下代码会创建一个 来自只读 chosenFileEntrywritableEntry,并将所选文件写入其中。

 chrome.fileSystem.getWritableEntry(chosenFileEntry, function(writableFileEntry) {
    writableFileEntry.createWriter(function(writer) {
      writer.onerror = errorHandler;
      writer.onwriteend = callback;

    chosenFileEntry.file(function(file) {
      writer.write(file);
    });
  }, errorHandler);
});

以下代码将使用“另存为”选项创建一个新文件功能,并将新的 blob 写入 使用 writer.write() 方法保存该文件。

chrome.fileSystem.chooseEntry({type: 'saveFile'}, function(writableFileEntry) {
    writableFileEntry.createWriter(function(writer) {
      writer.onerror = errorHandler;
      writer.onwriteend = function(e) {
        console.log('write complete');
      };
      writer.write(new Blob(['1234567890'], {type: 'text/plain'}));
    }, errorHandler);
});

使用 Chrome Sync Filesystem API

使用可同步的文件存储,可以采用与本地操作相同的方式操作返回的数据对象 FileSystem API 中的离线文件系统,但增加了(自动)同步该系统的功能 将数据导出到 Google 云端硬盘

添加同步文件系统权限

要使用 Chrome 的 Sync Filesystem API,您需将“syncFileSystem”对 以便从用户处获取存储和同步持久性数据的权限。

"permissions": [
  "...",
  "syncFileSystem"
]

正在启动可同步的文件存储

要在您的应用中启动可同步的文件存储,只需调用 syncFileSystem.requestFileSystem 即可。 此方法会返回 Google 云端硬盘支持的可同步文件系统,例如:

chrome.syncFileSystem.requestFileSystem(function (fs) {
   // FileSystem API should just work on the returned 'fs'.
   fs.root.getFile('test.txt', {create:true}, getEntryCallback, errorCallback);
});

关于文件同步状态

使用 syncFileSystem.getFileStatus 可获取当前文件的同步状态:

chrome.syncFileSystem.getFileStatus(entry, function(status) {...});

文件同步状态值可以是以下值之一:'synced''pending''conflicting'。 “已同步”表示文件已完全同步;您没有尚未完成的待更改本地更改 已同步到 Google 云端硬盘。不过,Google 云端硬盘中可能会有一些待更改项 尚未提取。

“待处理”表示文件中有尚未同步到 Google 云端硬盘的待更改项。如果应用 在线运行时,本地更改(几乎)会立即同步到 Google 云端硬盘,而 系统会以 'synced' 状态触发 syncFileSystem.onFileStatusChanged 事件(请参阅下文 )。

当文件的状态变为syncFileSystem.onFileStatusChanged 'conflicting'。“冲突”意味着本地存储空间和本地存储空间中 Google 云端硬盘。仅当冲突解决政策设置为 'manual'。默认政策为 'last_write_win',冲突会自动解决 简单的“最后写胜”政策可以通过以下方式更改系统的冲突解决政策: syncFileSystem.setConflictResolutionPolicy.

如果冲突解决政策设为 'manual' 且文件导致 'conflicting' 状态, 应用仍然可以将文件作为本地离线文件读取和写入,但是更改不会同步 并且文件将与在其他客户端上进行的远程更改取消关联,直到冲突 已解决。解决冲突的最简单方法是删除或重命名文件的本地版本。 这会强制同步远程版本,冲突状态得到解决, 系统会以 'synced' 状态触发 onFileStatusChanged 事件。

监听同步状态的变化

当文件的同步状态更改时,会触发 syncFileSystem.onFileStatusChanged 事件。 例如,假设某个文件有待更改项,且处于“待处理”状态。状态。该应用可能 处于脱机状态,以便可以同步更改。当同步服务检测到 本地更改,并将更改上传到 Google 云端硬盘时,该服务会触发 具有以下值的 onFileStatusChanged 事件: { fileEntry:a fileEntry for the file, status: 'synced', action: 'updated', direction: 'local_to_remote' }

同样,无论本地活动如何,同步服务都可能会检测到 另一个客户端,并将更改从 Google 云端硬盘下载到本地存储空间。如果遥控器 就会触发具有以下值的事件: { fileEntry: a fileEntry for the file, status: 'synced', action: 'added', direction: 'remote_to_local' }

如果本地端和远程端对同一文件的更改存在冲突,并且 分辨率政策设为'manual',文件状态已更改为conflicting状态, 与同步服务分离,并且在冲突解决之前不会进行同步。在本课中, 就会触发具有以下值的事件: { fileEntry: a fileEntry for the file, status: 'conflicting', action: null, direction: null }

您可以为此事件添加监听器,以响应任何状态变化。例如, Chrome 音乐播放器应用可收听从 Google 云端硬盘同步过来但尚未播放的任何新音乐 用户本地存储空间中的内容。找到的所有音乐都会同步到该设备 客户:

chrome.syncFileSystem.onFileStatusChanged.addListener(function(fileInfo) {
  if (fileInfo.status === 'synced') {
    if (fileInfo.direction === 'remote_to_local') {
      if (fileInfo.action === 'added') {
        db.add(fileInfo.fileEntry);
      } else if (fileInfo.action === 'deleted') {
        db.remove(fileInfo.fileEntry);
      }
    }
  }
});

检查 API 使用情况

要检查 API 使用的数据量,请查询应用的本地沙盒化目录或 syncFileSystem.getUsageAndQuota 返回的用量字节数:

chrome.syncFileSystem.getUsageAndQuota(fileSystem, function (storageInfo) {
   updateUsageInfo(storageInfo.usageBytes);
   updateQuotaInfo(storageInfo.quotaBytes);
});

您还可以查看用户的同步后端服务存储空间(位于 Google 云端硬盘中)。已同步的文件 保存在隐藏的 Google 云端硬盘文件夹 Chrome Syncable FileSystem。该文件夹不会显示在 您的“我的云端硬盘”但也可通过在搜索框中搜索文件夹名称来访问。(请注意, 不保证远程文件夹布局在各版本之间保持向后兼容。)