fwwdns tech blog

简介

我常常想,如果网络应用能够读取和写入文件与目录,将会非常方便。从离线转移到在线后,应用变得更加复杂,,而文件系统方面的API的缺乏也一直阻碍着网络前进。存储二进制数据或与其进行交互不应局限于桌面。令人欣慰的是,由于FileSystemAPI的出现,这一现状终于得到了改变。有了FileSystemAPI,网络应用就可以创建、读取、导航用户本地文件系统中的沙盒部分以及向其中写入数据。

API 被分为以下不同的主题:

读取和处理文件:File/Blob、FileList、FileReader

创建和写入:BlobBuilder、FileWriter

目录和文件系统访问:DirectoryReader、FileEntry/DirectoryEntry、LocalFileSystem

浏览器支持与存储限制

在写这篇文章时,只有 GoogleChrome 浏览器可以实施此FileSystemAPI。目前尚不存在专门用于文件/配额管理的浏览器用户界面。要在用户的系统上存储数据,您的应用可能需要。不过,可使用–unlimited-quota-for-files标记运行Chrome浏览器进行测试。此外,如果您要开发的是用于Chrome网上应用店的应用或扩展程序,可使用unlimitedStorage清单文件权限,而无需请求配额。最后,用户会收到授予、拒绝或为应用增加存储的权限对话框。

如果您要通过 file://调试您的应用,可能需要–allow-file-access-from-files标记。不使用这些标记会导致SECURITY_ERR或QUOTA_EXCEEDED_ERRFileError。

请求文件系统

网络应用可通过调用 window.requestFileSystem()请求对沙盒文件系统的访问权限:

// Note: The file system has been prefixed as of Google Chrome 12:window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;window.requestFileSystem(type, size, successCallback, opt_errorCallback)type文件存储是否应该是持久的。可能的值包括window.TEMPORARY和window.PERSISTENT。通过TEMPORARY存储的数据可由浏览器自行决定删除(例如在需要更多空间的情况下)。要清除PERSISTENT存储,必须获得用户或应用的明确授权,并且需要用户向您的应用授予配额。请参阅。size应用需要用于存储的大小(以字节为单位)。successCallback文件系统请求成功时调用的回调。其参数为 对象。opt_errorCallback用于处理错误或获取文件系统的请求遭到拒绝时可选的回调。其参数为对象。

如果您是首次调用requestFileSystem(),系统会为您的应用创建新的存储。请注意,这是沙箱文件系统,也就是说,一个网络应用无法访问另一个应用的文件。这也意味着您无法在用户硬盘上的任意文件夹(例如“我的图片”、“我的文档”等)中读/写文件。

用法示例:

FileSystem 规范还定义了计划用于的同步API()接口。不过,本教程不涉及该同步API。

在本文档的其余部分中,我们将使用相同的处理程序处理异步调用引发的错误:

function errorHandler(e) { var msg = ”; switch (e.code) {case FileError.QUOTA_EXCEEDED_ERR:msg = ‘QUOTA_EXCEEDED_ERR’;break;case FileError.NOT_FOUND_ERR:msg = ‘NOT_FOUND_ERR’;break;case FileError.SECURITY_ERR:msg = ‘SECURITY_ERR’;break;case FileError.INVALID_MODIFICATION_ERR:msg = ‘INVALID_MODIFICATION_ERR’;break;case FileError.INVALID_STATE_ERR:msg = ‘INVALID_STATE_ERR’;break;default:msg = ‘Unknown Error’;break; }; console.log(‘Error: ‘ + msg);}当然,这种错误回调非常通用,能让您充分理解,但您提供给用户的应是易于一般人理解的讯息。请求存储配额要使用 PERSISTENT 存储,您必须向用户取得存储持久数据的许可。由于浏览器可自行决定删除临时存储的数据,因此这一限制不适用于 TEMPORARY 存储。为了将 PERSISTENT 存储与 FileSystem API 配合使用,Chrome 浏览器使用基于 window.webkitStorageInfo 的新 API 以请求存储:window.webkitStorageInfo.requestQuota(PERSISTENT, 1024*1024, function(grantedBytes) { window.requestFileSystem(PERSISTENT, grantedBytes, onInitFs, errorHandler);}, function(e) { console.log(‘Error’, e);});用户授予许可后,就不必再调用 的属性和方法:fileEntry.isFile === truefileEntry.isDirectory === falsefileEntry.namefileEntry.fullPath…fileEntry.getMetadata(successCallback, opt_errorCallback);fileEntry.remove(successCallback, opt_errorCallback);fileEntry.moveTo(dirEntry, opt_newName, opt_successCallback, opt_errorCallback);fileEntry.copyTo(dirEntry, opt_newName, opt_successCallback, opt_errorCallback);fileEntry.getParent(successCallback, opt_errorCallback);fileEntry.toURL(opt_mimeType);fileEntry.file(successCallback, opt_errorCallback);fileEntry.createWriter(successCallback, opt_errorCallback);…为了更好地理解 FileEntry,本部分还提供了执行常规任务的众多技巧。创建文件您可以使用文件系统的 getFile()(接口的一种方法)查找或创建文件。请求文件系统后,系统会向成功回调传递FileSystem 对象,其中包含指向该应用相应文件系统的根的 DirectoryEntry (fs.root)。以下代码会在该应用相应文件系统的根中创建名为“log.txt”的空白文件:function onInitFs(fs) { fs.root.getFile(‘log.txt’, {create: true, exclusive: true}, function(fileEntry) {// fileEntry.isFile === true// fileEntry.name == ‘log.txt’// fileEntry.fullPath == ‘/log.txt’ }, errorHandler);}window.requestFileSystem(window.TEMPORARY, 1024*1024, onInitFs, errorHandler);请求文件系统后,系统会向成功处理程序传递 FileSystem 对象。我们可以将回调中的 fs.root.getFile() 命名为要创建的文件的文件名。您可以传递绝对路径或相对路径,但该路径必须有效。例如,如果您尝试创建一个其直接父级文件不存在的文件,将会导致出错。getFile() 的第二个参数是在文件不存在时从字面上说明函数行为的对象。在此示例中,create: true 会在文件不存在时创建文件,并在文件存在时 (exclusive: true) 引发错误。如果 create: false,系统只会获取并返回文件。无论是哪种情况,系统都不会覆盖文件内容,因为我们只是获取相关文件的引用路径。通过名称读取文件以下代码会检索名为“log.txt”的文件,并使用 FileReader API 读取文件内容,然后将其附加到页面上新的 <textarea>。如果 log.txt 不存在,系统将引发错误。function onInitFs(fs) { fs.root.getFile(‘log.txt’, {}, function(fileEntry) {// Get a File object representing the file,// then use FileReader to read its contents.fileEntry.file(function(file) {var reader = new FileReader();reader.onloadend = function(e) {var txtArea = document.createElement(‘textarea’);txtArea.value = this.result;document.body.appendChild(txtArea);};reader.readAsText(file);}, errorHandler); }, errorHandler);}window.requestFileSystem(window.TEMPORARY, 1024*1024, onInitFs, errorHandler);写入到文件以下代码会创建名为“log.txt”的空白文件(如果该文件不存在),并在文件中填入“Lorem Ipsum”文字。function onInitFs(fs) { fs.root.getFile(‘log.txt’, {create: true}, function(fileEntry) {// Create a FileWriter object for our FileEntry (log.txt).fileEntry.createWriter(function(fileWriter) {fileWriter.onwriteend = function(e) {console.log(‘Write completed.’);};fileWriter.onerror = function(e) {console.log(‘Write failed: ‘ + e.toString());};// Create a new Blob and write it to log.txt.var bb = new BlobBuilder(); // Note: window.WebKitBlobBuilder in Chrome 12.bb.append(‘Lorem Ipsum’);fileWriter.write(bb.getBlob(‘text/plain’));}, errorHandler); }, errorHandler);}window.requestFileSystem(window.TEMPORARY, 1024*1024, onInitFs, errorHandler);此时,我们会调用 FileEntry 的 createWriter() 方法获取 FileWriter 对象。在成功回调中为error 事件和 writeend 事件设置事件处理程序。通过以下操作将文字数据写入文件:创建 Blob,向 Blob 附加文字,然后将 Blob 传递到FileWriter.write()。向文件附加文字以下代码会将“Hello World”文字附加到日志文件结尾。如果该文件不存在,系统将引发错误。function onInitFs(fs) { fs.root.getFile(‘log.txt’, {create: false}, function(fileEntry) {// Create a FileWriter object for our FileEntry (log.txt).fileEntry.createWriter(function(fileWriter) {fileWriter.seek(fileWriter.length); // Start write position at EOF.// Create a new Blob and write it to log.txt.var bb = new BlobBuilder(); // Note: window.WebKitBlobBuilder in Chrome 12.bb.append(‘Hello World’);fileWriter.write(bb.getBlob(‘text/plain’));}, errorHandler); }, errorHandler);}window.requestFileSystem(window.TEMPORARY, 1024*1024, onInitFs, errorHandler);复制用户选定的文件在你成功地把自己推销给别人之前,你必须百

fwwdns tech blog

相关文章:

你感兴趣的文章:

标签云: