HTML5 File Access筆記 - 使用File System和寫入檔案

在製作一個Chrome extension時使用到HTML5 File Access相關的API,也因為是Chrome extension,所以這邊並無考慮cross browser的問題,各瀏覽器的支援度可以參考這裡

個人認為File System API的使用時機在有儲存檔案的需求,如果只是要讀取檔案(例如使用者上傳檔案的前置處理),File API可足夠使用。既然會儲存檔案就會需要用到File Writer API,所以File System和File Writer通常會一起使用,因為File System並不是讓瀏覽器可存取本機端的檔案,而是建立暫存(temporary)或保存(persistent)的儲存空間(Storage space)。基於安全性問題,File System API建立的儲存空間並不允許直接操作,也就是說無法像使用檔案總管一樣。所以剛建立的儲存空間當然是空的沒有任何檔案,要讀檔案也要先建立一些檔案。

API的命名預設是非同步(async),同步(sync)的會在function名稱後面加上Sync字尾,例如requestFileSystemSync。要開始使用File System前,必須先建立一個儲存空間。
var fs;
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(window.TEMPORARY, 1024 * 1024 * 5, function(filesystem){
    fs = filesystem;
}, fsErrorHandler);
這邊建立一個5MB大小的儲存空間,單位是bytes。建立好儲存空間後,開始操作前必須先取得根目錄(root directory),檔案和目錄都是一個Entry:DirectoryEntryFileEntry,都繼承自Entry interface。這個FileEntry並不是File API的File object。DirectoryEntry提供了名為getFile的方法來取得檔案。
var rootdir = fs.root;
rootdir.getFile(filename, {create: true}, function(fileEntry) {
    // callback
}, fsErrorHandler);
這裡簡單說明一下選項參數,有兩個屬性可以使用:create和exclusive。create很好懂,就是當檔案不存在時就建立新檔案;exclusive則是(根據spec的說明)『當create和exclusive都是true,而且檔案也已存在時,getFile會失敗』,簡單的說就是強制建立新檔案,如果檔案已存在,則應該回傳失敗。

FileEntry提供兩個方法(除了繼承自Entry interface):createWriter和file,就是寫和讀。file方法可以取得File instance(參考File API),createWriter則是回傳FileWriter instance(參考File Writer API)。把上面的程式碼多加些內容。
fs.root.getFile(name, {create: true}, function(fileEntry) {
    fileEntry.createWriter(function(fileWriter){
        fileWriter.onwriteend = function(e) {
            getFileURL(name, callback);
        };
        fileWriter.onerror = fsErrorHandler;
        fileWriter.write(new Blob([data], {type: "text/plain;charet=UTF-8"}));
    }, fsErrorHandler);
}, fsErrorHandler);
FileWriter繼承自FileSaver。要寫入檔案內容可使用write方法,write只接受Blob instance(參考File API)。上面這範例只註冊了writeend和error事件,FileSaver另外還提供了abort, progress, write, writestart事件。

大致上,使用File System並寫入檔案就如上所述。

Reference:
Exploring the FileSystem APIs - HTML5 Rocks
File Access - HTML5 Rocks
File API: Directories and System
File API
File API: Writer

留言

匿名表示…
請問window.requestFileSystem 可以在background.js執行嗎?
我在content.js儲存FileSystem沒有問題 但在background.js出錯 是不能在這裡執行嗎? 謝謝
Korprulu寫道…
基本上,extension的background script就是跑webworker,可以參考這篇http://www.html5rocks.com/en/tutorials/file/filesystem-sync/,或確認permission有沒有開啟file system

熱門文章