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使用示例