[Windows Phone] 開發宜蘭縣政府資料開放平台應用程式 (2) 將下載的 CSV 資料儲存到 Isolated Storage 提供下次進入應用程式時載入

在先前的文章 透過 Google Drive 放置宜蘭縣政府資料開放平台 CSV 檔案進行讀取 從 Google Drive 下載 CSV 資料,分析後顯示在畫面中。但每次都從網路下載 CSV 檔案,會導致應用程式執行時,需要有一段下載資料的時間,才能載入資料,因此本文提供作法,將下載後的 CSV 檔案儲存到 Isolated Storage 中,當 Isolated Storage 存在 CSV 檔案時,則讀取該資料,如果沒有的話,才從網路下載 CSV 檔案。

 

前言

在先前的文章 透過 Google Drive 放置宜蘭縣政府資料開放平台 CSV 檔案進行讀取 從 Google Drive 下載 CSV 資料,分析後顯示在畫面中。但每次都從網路下載 CSV 檔案,會導致應用程式執行時,需要有一段下載資料的時間,才能載入資料,因此本文提供作法,將下載後的 CSV 檔案儲存到 Isolated Storage 中,當 Isolated Storage 存在 CSV 檔案時,則讀取該資料,如果沒有的話,才從網路下載 CSV 檔案。

 

實作

請先下載先前文章 透過 Google Drive 放置宜蘭縣政府資料開放平台 CSV 檔案進行讀取 的範例,我們先撰寫兩個方法來讀取和儲存 CSV 檔案。

讀取

 

        /// <summary>
        /// 從 Isolated Storage 讀取 CSV 檔案資料
        /// </summary>
        /// <param name="isoStorageFileName">CSV 檔案名稱</param>
        /// <returns>檔案內容字串</returns>
        private string ReadCsvFormIsolated(string isoStorageFileName)
        {
            string strCsvData = string.Empty;
            using (IsolatedStorageFile isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (isolatedStorageFile.FileExists(isoStorageFileName))
                {
                    IsolatedStorageFileStream fileStream = isolatedStorageFile.OpenFile(isoStorageFileName, FileMode.Open, FileAccess.Read);
                    using (StreamReader streamReader = new StreamReader(fileStream))
                    {
                        strCsvData = streamReader.ReadToEnd();
                    }
                }
            }
            return strCsvData;
        }

 

儲存

 

        /// <summary>
        /// 儲存 CSV 資料到 Isolated Storage
        /// </summary>
        /// <param name="isoStorageFileName">CSV 檔案名稱</param>
        /// <param name="strCsv">CSV 字串內容</param>
        private void SaveCsvToIsolatedStorage(string isoStorageFileName, string strCsv)
        {
            using (IsolatedStorageFile isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (isolatedStorageFile.FileExists(isoStorageFileName))
                {
                    isolatedStorageFile.DeleteFile(isoStorageFileName);
                }
                using (var stream = isolatedStorageFile.CreateFile(isoStorageFileName))
                {
                    using (StreamWriter streamWriter = new StreamWriter(stream))
                    {
                        streamWriter.WriteLine(strCsv);
                    }
                }
            }
        }

 

在 GetHttpDocumentCallback() 方法中,將處理 CSV 字串的部分的程式碼選取,按滑鼠右鍵,選擇 [重構] / [擷取方法],擷取方法為名稱 ProcessCsvStream 的方法,將處理 CSV 資料的部分選起來。

 

image

 

新方法名稱為 ProcessCsvData,按 [確定]。

SNAGHTML252e304[7]

 

ProcessCsvData 方法的程式碼:

        /// <summary>
        /// 處理 CSV 字串
        /// </summary>
        /// <param name="strCsvData">CSV 字串內容</param>
        private void ProcessCsvData(string strCsvData)
        {
            using (TextReader textReader = new StringReader(strCsvData))
            {
                using (var reader = new CsvReader(textReader))
                {
                    reader.ReadHeaderRecord();

                    while (reader.HasMoreRecords)
                    {
                        var record = reader.ReadDataRecord();
                        Deployment.Current.Dispatcher.BeginInvoke(new Action(() =>
                        {
                            this.Items.Add(new ItemViewModel()
                            {
                                LineOne = record.GetValueOrNull("中文名稱"),
                                LineTwo = record.GetValueOrNull("聯絡電話"),
                                LineThree = record.GetValueOrNull("民宿中文地址")
                            });
                        }));
                    }
                }
            }
        }

 

在 GetHttpDocumentCallback() 方法中,加入先前撰寫的方法 SaveCsvToIsolatedStorage 做 [將下載後的 CSV 檔案儲存到 Isolated Storage 中]。最後 GetHttpDocumentCallback 的程式碼:

 

        /// <summary>
        /// 非同步網路資源要求與下載
        /// </summary>
        /// <param name="iAsyncResult"></param>
        private void GetHttpDocumentCallback(IAsyncResult iAsyncResult)
        {
            HttpWebRequest httpWebRequest = (HttpWebRequest)iAsyncResult.AsyncState;
            HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.EndGetResponse(iAsyncResult);
            using (StreamReader responseStream = new StreamReader(httpWebResponse.GetResponseStream()))
            {
                string strCsvData = responseStream.ReadToEnd();
                if (string.IsNullOrEmpty(strCsvData))
                {
                    return;
                }

                // 處理 CSV 字串資料
                ProcessCsvData(strCsvData);

                // 儲存 CSV 資料到 Isolated Storage
                SaveCsvToIsolatedStorage("HomeStay.csv", strCsvData);
            }
        }

 

接著我們在 Load 方法,撰寫邏輯 [當 Isolated Storage 存在 CSV 檔案時,則讀取該資料,如果沒有的話,才從網路下載 CSV 檔案。]。

 

        /// <summary>
        /// 建立並加入一些 ItemViewModel 物件到 Items 集合。
        /// </summary>
        public void LoadData()
        {
            // 當 Isolated Storage 存在 CSV 檔案,則讀取該資料
            string strCsvData = ReadCsvFormIsolated("HomeStay.csv");
            if (string.IsNullOrEmpty(strCsvData) == false)
            {
                // 處理 CSV 資料
                ProcessCsvData(strCsvData);
            }
            else  // 如果沒有的話,才從網路下載 CSV 檔案
            {
                HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create("https://docs.google.com/uc?export=download&id=0B34Keu0W_LIJODdEYUhVSDZIS28");
                httpWebRequest.BeginGetResponse(new AsyncCallback(GetHttpDocumentCallback), httpWebRequest);
            }         

            this.IsDataLoaded = true;
        }

 

執行程式,透過以下影片錄製模擬器運作應用程式時的過程,第一次時由於 Isolated Storage 不存在檔案,因此會從網路下載 CSV 檔案進行分析與顯示資料,顯示資料時間很慢。當離開應用程式並且再次執行應用程式時,由於先前已經下載過資料並且儲存到 Isolated Storage 中,直接讀取其中的內容,因此速度會快很多。

 

將下載的 CSV 資料儲存到 Isolated Storage 提供下次進入應用程式時載入

 

範例下載

HomeStayApp.zip

 

課後作業

加入一個 Applcation Bar 按鈕,功能是讓使用者點選後,從網路下載 CSV 進行解析並且更新畫面資料,並且儲存檔案至 Isolated Storage 中。