【Win 10 应用开发】文件读写的三种方案
本文老周就跟伙伴們探討一下關于文件讀寫的方法。總得來說嘛,有三種方案可以用,而且每種方案都各有特色,也說不上哪種較好。反正你得記住老祖宗留給我們的大智慧——事無定法,靈活運用者為上。
OK,咱們開始吧。
?
先說第一個方案:使用 FileIO類。
這個類屬于RT庫API,它公開了一堆靜態方法,可以直接調用,快捷方便,就像.net里面的File類一樣。在使用FileIo類的時候,需要一個引用已知文件的StorageFile實例,而且FileIo只能操作已經存在的文件,它不會自動創建文件,這一點要注意。
下面代碼演示如何用FileIO類把文本內容寫入文件中。
// 獲取文檔庫StorageFolder doclib = KnownFolders.DocumentsLibrary;// 創建新文件StorageFile newfile = await doclib.CreateFileAsync("test.txt", CreationCollisionOption.OpenIfExists);// 將文本寫入文件await FileIO.WriteTextAsync(newfile, content, UnicodeEncoding.Utf8);在讀寫文本的時候,強烈建議明確指定為UTF-8編碼,這樣做可以減少靈異事件發生的概率,信不信由你。
在調用CreateFileAsync方法創建新文件時,可以同時只定一個CreationCollisionOption枚舉的值,如果值為FailIfExists,表示當文件已經存在時會引發異常;我這里選用OpenIfExists,即如果文件不存在就創建,如果存在就打開現有文件;如果值為ReplaceExisting,就替換現有文件。
?
下面代碼讀從剛才保存的文件中將文本讀出來。
try{// 訪問文檔庫StorageFolder doclib = KnownFolders.DocumentsLibrary;// 獲取剛才保存的文件StorageFile file = await doclib.GetFileAsync(filename);if (file != null){// 讀入內容displayContent = await FileIO.ReadTextAsync(file, UnicodeEncoding.Utf8);}}catch (FileNotFoundException){displayContent = "文件不存在。";}catch (Exception ex){displayContent = ex.Message;}如果要打開的文件不存在,會引發FileNotFoundException異常,所以我特特地捕捉這個異常,為的是在文件不存在時向用戶反饋。
這里有個關鍵點,大家要記清,你寫入文本時用的是Utf-8編碼,在讀出來的時候也要使用匹配的編碼格式,在民政局登記領證時,你總不能寫別人家老婆的名字吧。
?
第二種方案用的也是RT庫的API,即DataWriter和DataReader類。這與FileIO還是有不同的,FileIO所針對的文件對象,而DataReader和DataWriter所針對的是流,文件流、內存流、網絡流都可以用,它們所面向的應用范圍不同,當然,是可以用來讀寫文件流的。
下面代碼演示將當前時間寫入文件。
// 獲取文檔庫StorageFolder doclib = KnownFolders.DocumentsLibrary;// 創建文件StorageFile file = await doclib.CreateFileAsync("new.txt", CreationCollisionOption.ReplaceExisting);// 打開文件流using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite)){DataWriter dw = new DataWriter(stream);// 寫入時間 dw.WriteDateTime(DateTimeOffset.Now);// 提交數據到流await dw.StoreAsync();// 收工 dw.Dispose();}在調用StorageFile的OpenXXXAsync方法可以打開用來讀寫文件的流,要是想讓打開的流支持寫入行為,應該調用OpenAsync方法,并在參數中傳遞FileAccessMode.ReadWrite值,說明可讀可寫,如果是Read,那就只能讀不能寫了。當然了,如果是只讀的話,也可以直接調用OpenReadAsync方法。
DataWriter類公開了N個WriteXXXXX方法,可以寫入許多基礎類型,比如字節、int、double、字符串等,當然也包括日期時間。
大家要記住,在你寫完數據后,記得調用StoreAsync方法,因為writer在寫入時不會馬上就寫入流中,它是先把數據寫入到緩沖區中,等到StoreAsync方法調用后,就會把緩沖區中的內容寫入流,然后清理緩沖區。
在DataWriter的緩沖區中存在沒有保存到流的數據時,UnstoredBufferLength屬性可返回未保存的數據大小,如果調用StoreAsync后,這個屬性會變為0。
?
下面代碼演示讀出剛剛保存到文件中的時間。
// 獲取文件StorageFile file = await doclib.GetFileAsync(filename);if (file != null){// 打開流using(IRandomAccessStream stream = await file.OpenReadAsync()){// 讀出時間using (DataReader dr=new DataReader(stream)){await dr.LoadAsync((uint)stream.Size);DateTimeOffset dt = dr.ReadDateTime();displaystr = dt.ToString("yyyy年M月d日 HH:mm:ss");}}}}catch (FileNotFoundException){displaystr = "未找到文件。";}catch (Exception ex){displaystr = ex.Message;}實例化DataReader后,不要急著讀,因為數據還在流中,不在reader的緩沖區中,所以,你應當先調用LoadAsync方法來加載內容,參數是要加載的字節數,返回值是實際加載的大小。加載好之后,你就可以讀了。
?
第三種方案是混合.NET和RT庫的API來讀寫。在System.IO命名空間下,定義了兩個擴展類。
第一個是WindowsRuntimeStorageExtensions,它是針對StorageFile類的擴展,比如,調用OpenStreamForWriteAsync方法就可以直接得到一個.net中的Stream實例,這樣你就可以用慣用的.net方式來讀寫了。
另一個是WindowsRuntimeStreamExtensions,它是針對流的擴展,支持將.net中的流與RT中的流進行相互轉換。
有人會問了,既然有RT的API了,為什么還要讓它與.net交互呢。你想想就知道了。
1、UWP支持的編寫語言中有JS、C++,也有VB.NET和C#,C#和VB都是基于.net的語言,所以在UWP應用代碼中你才能使用C#的基本類型,如int,byte,double,bool,string,float等,就是因為它是兩個API子集的合體,沒有.net core就無法用這些語言寫代碼了。
2、如果一些第三方類庫使用的是.net core開發的可以跨平臺移植的呢,那也得需要這種交互才能相互調用。
?
其實這沒什么難理解的,就像中西藥可以結合一起用一樣的道理,把腦子放靈活一點就沒什么不能理解的了。
?
下面代碼演示寫入文件。
StorageFile file = await doclib.CreateFileAsync("some.txt", CreationCollisionOption.ReplaceExisting);Tag = file.Name;using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite)){// 轉化為.net IO 流using (StreamWriter writer = new StreamWriter(stream.AsStreamForWrite(), System.Text.Encoding.UTF8)){// 寫入內容 writer.Write(content);}}?
下面代碼演示讀出內容。
try{StorageFile file = await doc.GetFileAsync(filename);using (IRandomAccessStream stream = await file.OpenReadAsync()){using (StreamReader rd = new StreamReader(stream.AsStreamForRead(), System.Text.Encoding.UTF8)){tb.Text = rd.ReadToEnd();}}}catch (FileNotFoundException){tb.Text = "未找到文件。";}catch (Exception ex){tb.Text = ex.Message;}?
StreamWriter和StreamReader我就不介紹了,在.net里面玩得多了。
?
?
行了,三種方案都介紹完了,至于怎么用,自己看著辦吧,還是那句話——事無定法。
?
示例源代碼下載
?
========================================================
下面時間,講個小故事。
你要是問我:老周,你的記憶力是不是特別好。
還真是,但那是小時候,不知道為什么,越長大好像記憶力越后退。想想老周上小學的時候,從來不復習都可以考全級第一名,當然,全級總人數也就90來人,呵呵。
就連語文課本上要背的課文、古詩,英語課本上的對話,老周都不用課后去背,直接在課堂上完成,回家后壓根不用復習。也不知道什么原因,那個時候真的可以說是過目不忘。
上了初中后就不太行了,看一遍根本記不下來,少說也要看兩到三遍,尤其是背文言文。反正總感覺年齡大了,記憶力衰退。小時候可以過目不忘的本領全沒了,現在拿一首唐詩出來,我起碼也得讀上N遍,抄上M回才能背下來,根本失去了小時候那種可以看一遍就背下來的能力了。
唉,想來歲月真是一把手術刀,把記憶力都一刀一刀地削去了。
?
總結
以上是生活随笔為你收集整理的【Win 10 应用开发】文件读写的三种方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微软发布紧急更新:修复Flash高危漏洞
- 下一篇: kettle中使用javascript步