首頁 > web前端 > H5教程 > 主體

HTML5檔案操作API的程式碼案例詳解

黄舟
發布: 2018-05-26 10:14:06
原創
4886 人瀏覽過

簡介

我常常想,如果網路應用程式能夠讀取和寫入檔案與目錄,將會非常方便。從離線轉移到線上後,應用程式變得更加複雜,而檔案系統方面的API的缺乏也一直阻礙著網路前進。儲存二進位資料或與其進行互動不應局限於桌面。令人欣慰的是,由於FileSystemAPI的出現,這一現狀終於改變了。有了FileSystemAPI,網路應用程式就可以建立、讀取、導航使用者本機檔案系統中的沙盒部分以及向其中寫入資料。

API 被分成以下不同的主題:

  • #讀取和處理檔案:File/ BlobFileListFileReader

  • 建立和寫入:BlobBuilder##、FileWriter

  • 目錄和檔案系統存取:

    DirectoryReaderFileEntry/DirectoryEntry##LocalFileSystem

  • 瀏覽器支援與儲存限制

在寫這篇文章時,只有

GoogleChrome

瀏覽器可以實作此FileSystemAPI 。目前尚不存在專門用於檔案/配額管理的瀏覽器使用者介面。要在使用者的系統上儲存數據,您的應用程式可能需要請求配額。不過,可使用--unlimited-quota-for-files標記執行Chrome瀏覽器進行測試。此外,如果您要開發的是用於Chrome線上應用程式商店的應用程式或擴充程序,可使用unlimitedStorage清單檔案權限,而無需請求配額。最後,使用者會收到授予、拒絕或為應用程式增加儲存的權限對話框。 如果您要透過

file://#調試您的應用程式,可能需要--allow-file-access-from-files 標記。不使用這些標記會導致SECURITY_ERRQUOTA_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

檔案系統請求成功時呼叫的回呼。其參數為 FileSystem物件。

opt_errorCallback

用於處理錯誤或取得檔案系統的請求遭到拒絕時可選的回呼。其參數為FileError物件。

如果您是首次呼叫requestFileSystem(),系統會為您的應用程式建立新的儲存體。請注意,這是沙箱檔案系統,也就是說,一個網路應用程式無法存取另一個應用程式的檔案。這也意味著您無法在使用者硬碟上的任意資料夾(例如「我的圖片」、「我的文件」等)中讀取/寫入檔案。

用法範例:

function onInitFs(fs) {
  console.log('Opened file system: ' + fs.name);}
  window.requestFileSystem(window.TEMPORARY, 5*1024*1024 /*5MB*/, onInitFs, errorHandler);
登入後複製

FileSystem 規格也定義了計畫用於WebWorkers的同步API(LocalFileSystemSync)介面。不過,本教學不涉及該同步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);  
});
登入後複製

用户授予许可后,就不必再调用 requestQuota() 了。后续调用为无操作指令。您还可以使用 API 查询源的当前配额使用情况和分配情况:window.webkitStorageInfo.queryUsageAndQuota()使用文件沙盒环境中的文件通过 FileEntry 接口表示。FileEntry 包含标准文件系统中会有的属性类型(name、isFile...)和方法(remove、moveTo、copyTo...)。FileEntry 的属性和方法:

fileEntry.isFile === true  
fileEntry.isDirectory === false  
fileEntry.name  
fileEntry.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()(DirectoryEntry 接口的一种方法)查找或创建文件。请求文件系统后,系统会向成功回调传递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 读取文件内容,然后将其附加到页面上新的