WP7 -下載檔案至Isolated Storage

Windows Phone 7下載檔案至Isolated Storage

上一篇介紹了Isolated Storage的概念之後,我在想之前撰寫的開發Windows Mobile簡單dict字典-以SQLite為例

要怎麼把他放置到Windows Phone 7中,讓這個程式也能正常的活下去。因為上一篇提到,Isolated Storage是獨

立的運作記憶體,如果要直接把.db(SQLite Database)放進去,透過正常的匯入到\Debug\bin資料夾是沒有用的。

當然,我也有想過,像一般在Silvelight程式中使用到的圖片,透過Image控件的source屬性來自動匯入到指定的

資料夾中,這個方式我沒有適過。但也許可以

總而言之呢,後來我覺得既然是字典嘛,總是要不斷地更新才能保持字數與內容的完整性、豐富性,所以就決

定改透過下載到Isolated Storage的方式,讓該WP7程式自己操作它。因此,我尋找了幾篇關於SQLite on WP7的

使用,簡單介紹一下:

Sqlite for WP 7 Series - Proof of concept

這一篇裡面有demo的範例程式,介紹如何在WP7如何操作SQLite,以下簡單的取出幾個重要的片段。

[基本運作]

a. 需要變數:rc(儲存執行結果);errMsg(儲存錯誤訊息);Sqlite3.sqlite3(DB物件)。以OpenDB為例。

   1: public void OpenDB()
   2: {
   3:   string tDBFileName="cdict-big5.db";
   4:   int tRc;
   5:   Sqlite3.sqlite3 tDBFile = new Sqlite3.sqlite3();
   6:   tRc = Sqlite3.sqlite3_open(tDBFileName, ref tDBFile);
   7:   if (rc != 0)
   8:   {
   9:     MessageBox.Show("資料庫開啟失敗!" + Sqlite3.sqlite3_errmsg(tDBFile));
  10:   } else{
  11:     MessageBox.Show("資料庫開啟成功!");
  12:   }
  13: }

b. 重要操作的方法:

b-1. 執行SQL語法。主要透過Sqlite3.sqlite3_open先開啟資料庫連線,再透過Sqlite3.sqlite3_exec執行SQL語法。

可以注意呼叫callback方式的部分,它透過了Sqlite3.dxCallback讓Sqlite3執行的結果,透過delegate(委派)的

方式指給callback來顯示執行的結果

   1: public void Query(){
   2:   int tRc;
   3:   string tErrorMsg = string.Empty;
   4:   Sqlite3.sqlite3 tDBFile = new Sqlite3.sqlite3();
   5:   tRc = Sqlite3.sqlite3_open(tFileName, ref tDBFile);
   6:   if (tRc != 0)
   7:   {                        
   8:   }
   9:   tRc = Sqlite3.sqlite3_exec(tDBFile, "SELECT word FROM Vocabulary WHERE word like 'accust%'", 
  10:         (Sqlite3.dxCallback)this.callback, null, ref tErrorMsg);
  11:   if (tRc != Sqlite3.SQLITE_OK)
  12:   {
  13:     MessageBox.Show("執行SQL失敗!"+Sqlite3.sqlite3_errmsg(tDBFile);
  14:   }
  15:   Sqlite3.sqlite3_close(tDBFile);
  16: }

b-2. callback方法。該方法作於該類別執行SQL語法(如:Select)之後的回傳值。如下程式碼:

   1: public int callback(object pArg, System.Int64 nArg, object azArgs, object azCols)
   2: {
   3:   int i;
   4:   string[] azArg = (string[])azArgs;
   5:   string[] azCol = (string[])azCols;
   6:   String sb="";// = new String();
   7:   for (i = 0; i < nArg; i++)            
   8:       sb+=azCol[i] + " = " + azArg[i] + "\n";            
   9:   MessageBox.Show(sb.ToString());
  10:   return 0;
  11: }

它將執行結果的透過nArg(代表有幾個column);azArgs(對應Column的值);azCols(對應Column的名稱),透過

For回圈把所有的值一一列出來。不過這個callback的呼叫會依照執行SQL的結果來觸發,例如:Select回來如

果有二筆資料的話,該callback會被呼叫二次。

 

以上介紹完SQLite在WP7上運作之後,還是要回到本篇的主題上,以下就介紹透過WebClient來完成下載檔案

到Isolated Storage的方式:

1. 建立一個當WebClient下載完成時,要獨立處理的OpenReadCompletedEventHandler事件。如下範例:

   1: protected void DownloadCompleteHandler(object sender, OpenReadCompletedEventArgs e)
   2: {
   3:   using (var tStore = IsolatedStorageFile.GetUserStoreForApplication())
   4:   {
   5:       //取得檔案名稱,並且檢查是否已經有檔案存在,如果有則先刪除,再重新寫入。
   6:       string tFileName = "cdict-big5.db";
   7:       if (tStore.FileExists(tFileName))
   8:       {
   9:           tStore.DeleteFile(tFileName);
  10:       }
  11:       using (var tFStream = new IsolatedStorageFileStream(tFileName, FileMode.Create, tStore))
  12:       {
  13:           byte[] tByteInStream = new byte[e.Result.Length];
  14:           e.Result.Read(tByteInStream, 0, (int)tByteInStream.Length);
  15:           tFStream.Write(tByteInStream, 0, tByteInStream.Length);
  16:           tFStream.Flush();
  17:       }
  18:   }
  19: }

透過該方法,我們可以在指定URL中的檔案讀取(下載)完成後,將它透過Byte[]的方式寫入到檔案之中。

其實儲存檔案的方式,就跟我們撰寫透過ASP.NET下載的程式差不多。

2. 將獨立的OpenReadCompletedEventHandler事件Bind WebClient控件的OpenReadCompleted事件。如下:

   1: //指定下載檔案的位置,此範例透過絕對URI路徑。
   2: string tDBfile = "http://localhost/PageAdjust/cdict-big5.db";
   3:  
   4: WebClient tWClient = new WebClient();
   5: //Binding OpenReadCompleted事件於獨立的OpenReadCompletedEventHandler。
   6: tWClient.OpenReadCompleted += new OpenReadCompletedEventHandler(this.DownloadCompleteHandler);
   7:  
   8: tWClient.OpenReadAsync(new Uri(tDBfile, UriKind.Absolute));

透過上方二段的程式就可以把我製作的開發Windows Mobile簡單dict字典-以SQLite為例資料庫檔,從遠端

下載到WP7,並且配合上方介紹SQLite on WP7的說明,即可快速將原本為WM建立的程式翻版成WP7版。

分享簡單的下載檔案到Isolated Storage方式給大家,當個紀錄。

 

References:

Storing and playing media on Windows Phone 7

http://sviluppomobile.blogspot.com/2010/03/sqlite-for-wp-7-series-proof-of-concept.html

http://agilemobility.net/2010/04/more-windows-phone-7-silverlight-development-tutorials/

http://agilemobility.net/2010/06/winphone7db-on-codeplex/

Windos phone7的Isolated storage使用示例