PhoneGap:檔案存取(二)

檔案存取(一)提供純文字文件存取、刪除的語法,以及取得檔案列表物件,不過對於實際應用上沒有著墨。本篇提供自行建立function的簡單範例,並進一步說明其作用。

onLoadFunction

onLoadFunction() 是在 FileSystem 初始化完成後呼叫。通常裡面會做的事情只有三種,分別是指定檔案目錄、檔案列表以及讀取檔案。當然,這三種事情是不會擺在一起執行的。當網頁載入時,若沒有要預先做任何事情,也不需要特別呼叫 onLoadFunction()。

function onLoadFunction() {
    //setDirectory("myDirectory");  //指定檔案目錄
    //listFiles();          //檔案列表
    //loadFile(filename);       //讀取檔案
}

afterSetDirectory

如果系統執行 setDirectory(),之後便會接著執行 afterSetDirectory()。通常我們在同一個網頁中,只會針對某一個目錄做存取。在這種狀況之下,就可以在 onLoadFunction 時設定目錄,並且在設定完成後讀取檔案或列表。當然,如果檔案都只放在根目錄的話,就不需要寫 setDirectory() 以及 afterSetDirectory() 了。

function onLoadFunction() {
    setDirectory("myDirectory");    //指定檔案目錄
}
function afterSetDirectory() {
    //listFiles();          //檔案列表
    //loadFile(filename);       //讀取檔案
}

saveFileSuccess

存檔時呼叫的是 saveFile(filename, content),存檔完成之後則會呼叫 saveFileSuccess(filename)。如果覺得這個函式不重要,就大錯特錯了。相信沒有人希望系統”存檔失敗”的吧。可是當我們沒有在 saveFileSuccess 確認存檔完成時,很多時候檔案會”漏存”,由其是當行動載具執行速度不夠快的時候。舉個例子,當我們執行存檔之後,網頁就跳頁了(甚至關閉APP),可是因為程式沒有執行 saveFileSuccess 確認,所以當系統儲存到一半的時候,突然跳頁於是程式執行中斷,檔案就沒有儲存到了。所以無論是要跳頁或是關閉程式,請先在這裡確認檔案存檔完成才執行。

function saveFileSuccess(filename) {
    //location.href= "";        //跳轉網頁
    //navigator.app.exitApp();  //關閉程式
}

由於每次儲存完都會呼叫 saveFileSuccess(),若是沒有回傳檔名,就不知道目前儲存的是那一個檔案。所以若是此網頁可能儲存二個以上的檔案時,記得要寫判斷式。

displayEntries

在我們呼叫 listFiles() 後,會在 displayEntries() 回傳 entry 物件陣列,這個物件裡存的就只是一些檔案資訊而已。這裡順便提供一種寫法,是當我們要把APP裡所有目錄的檔案列出來時,可以參考的程式碼。

var dir = "";       //目前所在的目錄
var waitDir = [];   //待讀取的目錄
function onLoadFunction() {
    listFiles();
}
function afterSetDirectory() {
    listFiles();
}
function displayEntries(entries) {  //讀取存檔清單
    entries.forEach(function(entry, i) {
        if(!entry.isFile) waitDir.push(entry.name); //儲存目錄
        else {
            //列出檔案
            //entry.isFile  //此entry是否為檔案
            //entry.name    //取得名稱
            //entry.toURL() //取得位置

            //$("#fileList").append("

  • <a onClick=\"#\">

    "+entry.name+"

    "+entry.toURL()+"

  • "); } }); if(waitDir.length != 0) { //有目錄未讀取 dir = waitDir.pop(); //取出未讀取目錄 setDirectory(dir); //指定檔案目錄 } else { //結束讀取檔案清單 //$("#fileList").listview('refresh'); } }

    第 1 行的變數是儲存目前所在的目錄位置,當程式執行完畢時,可以透過此變數掌握當前的目錄位置。第 2 行的陣列只是用來暫存待讀取的目錄。第 3-5 行是當網頁載入後,執行第一次的 listFiles()。第 6-8 行則是在每次設定完目錄後,繼續執行 listFiles(),以列出當前目錄中的檔案。所以 listFiles() 的執行次數會是”目錄的數量+1”次(多的那一次是根目錄)。

    第 9 行開始是每次執行 listFiles() 後要做的事。第 10 行用一個 for 迴圈讀取每一個 entry 物件。無論是目錄或檔案,entry 物件都是一樣的,所以使用 entry.isFile 判斷是否為檔案。如果是目錄,第 11 行將目錄名稱儲存到 waitDir 陣列中。如果是檔案,則做我們需要的處理,可以用 jQuery mobile 的 listview 列出來,或是用一般的項目符號列出,第 18 行提供了一個顯示的範例。

    當前的目錄讀取完畢之後,第 21 行的判斷式表示 waitDir 裡有未讀取的目錄,第 22 行取出其中一個目錄後,在第 23 行設定讀取目錄。於是設定完成之後,就會回到 6-8 行,然後再一次呼叫第 9 行的函式。直到 waitDir 裡面沒有東西時,才會呼叫第 25-28 行。如果是使用 jQuery mobile 的 listview,結束時必須執行 27 行的 refresh 方法,這樣檔案清單才會更新。

    必須注意的一點是,這樣的程式碼只適用”一層的子目錄”,若是有二層以上的子目錄,這隻程式就不會那麼簡單了。由於存檔的內容都是純文字,所以其實可以利用副檔名來區分不同的儲存內容,例如使用者的資料或是系統log等等。