C#開發(fā)Winform實現(xiàn)文件操作案例
一、文件對話框
C#中共有三種文件對話框,分別用于不同的功能:
- (1)用于打開文件的對話框OpenFileDialog。
- (2)用于保存文件的對話框SaveFileDialog。
- (3)打開文件夾的對話框FolderBroswerDialog。
示例:如下圖,點擊三個按鈕分別彈出三種對話框,進(jìn)行相應(yīng)操作之后,將路徑在文本框中顯示:
(1)OpenFileDialog對話框
修改OpenFileDialog對話框的Name屬性為ofDlg。在“打開”按鈕添加ofDlg.ShowDialog(); 界面如下:
通過ShowDialog()的返回值,判斷點擊的是“打開”還是“取消”。在“打開”按鈕點擊事件中編寫如下代碼:
private void btnOpen_Click(object sender, EventArgs e) { //判斷是否點擊的“打開”按鈕 if (ofDlg.ShowDialog() == DialogResult.OK) { txtPath.Text = ofDlg.FileName; } }
OpenFileDialog常用屬性表:
屬性名 | 功能說明 |
---|---|
InitialDirectory | 對話框的初始目錄 |
Filter | 文件篩選器,按"顯示名稱|類型"格式編寫 例如,"文本文件(.txt)|.txt|所有文件(.)||." |
FilterIndex | 在對話框中選擇的文件篩選器的索引,如果選第一項就設(shè)為1 |
FileName | 第一個在對話框中顯示的文件或最后一個選取的文件 |
Title | 將顯示在對話框標(biāo)題欄中的字符 |
CheckFileExists | 在用戶指定不存在的文件時是否顯示警告 |
CheckPathExists | 在對話框返回之前,檢查指定路徑是否存在 |
(2)SaveFileDialog對話框
保存文件對話框常用于軟件中的“另存為”功能。其常用屬性、方法及使用方式與打開文件對話框相同。
設(shè)置保存文件對話框的Filter屬性為“文本文件|*.txt”。在“保存”按鈕的點擊事件中編寫如下代碼:
private void btnSave_Click(object sender, EventArgs e) { if (sfDlg.ShowDialog() == DialogResult.OK) { txtPath.Text = sfDlg.FileName; } }
(3)FolderBroswerDialog對話框
瀏覽文件夾對話框常用于瀏覽文件夾,選擇文件夾路徑。
在“瀏覽”按鈕的點擊事件中編寫如下代碼:
private void btnBrowse_Click(object sender, EventArgs e) { if (fbDlg.ShowDialog() == DialogResult.OK) { txtPath.Text = fbDlg.SelectedPath; } }
FolderBroswerDialog常用屬性:
屬性名 | 能說明功 |
---|---|
Description | 顯示在對話框的樹視圖上方的字符串,用來指定顯示給用戶的指導(dǎo)信息 |
RootFolder | 設(shè)置根文件夾位置 |
SelectedPath | 對話框中最先選擇的文件夾或用戶最后選擇的文件夾完整路徑 |
ShowNewFold | 對話框中是否包括“新建文件夾”按鈕 |
二、文件及文件夾操作
文件及文件夾管理是操作系統(tǒng)的重要組成部分,主要包括創(chuàng)建、移動、復(fù)制和刪除等操作。
Directory類和DirectoryInfo類用于對磁盤和文件夾的操作管理。
File類和FileInfo類用于對文件進(jìn)行常用操作管理。
(1)文件常用操作
在C#中如果對文件進(jìn)行創(chuàng)建、復(fù)制和刪除等少量操作一般使用File類。
File類是靜態(tài)類,其中所有方法都是靜態(tài)的,通過類名直接調(diào)用,不需要實例化。
示例,如下圖,進(jìn)行文件的基本操作:
點擊"選擇文件"按鈕選擇某個文件,并將文件路徑在文本框顯示。
點擊"選擇文件夾"按鈕選擇某個文件夾,并將文件夾路徑在文本框顯示。
點擊"復(fù)制文件"按鈕,實現(xiàn)將文件復(fù)制到文件夾中。
點擊"移動文件"按鈕,實現(xiàn)將文件移動到文件夾中。
點擊"刪除文件"按鈕,實現(xiàn)將文件刪除。
其中,"選擇文件"按鈕name=btOpenFile,"選擇文件夾"按鈕name=btOpenFolder,"復(fù)制文件"按鈕name=btCopy,"移動文件"按鈕name=btMove,"刪除文件"按鈕name=btDelete。
存放文件名的文本框name=txtFile,存放文件夾名的文本框name=txtFolder。
文件對話框name=openFileDialog1,文件夾對話框name=folderBrowserDialog1。
File類實現(xiàn)代碼如下:
//選擇文件按鈕 private void btOpenFile_Click(object sender, EventArgs e) { if (this.openFileDialog1.ShowDialog() == DialogResult.OK) { //FileName包含路徑,SafeFileName不包含路徑 this.txtFile.Text = this.openFileDialog1.FileName; } } //選擇文件夾按鈕 private void btOpenFolder_Click(object sender, EventArgs e) { if (this.folderBrowserDialog1.ShowDialog() == DialogResult.OK) { this.txtFolder.Text = this.folderBrowserDialog1.SelectedPath; } } //復(fù)制文件按鈕 private void btCopy_Click(object sender, EventArgs e) { if (!File.Exists(this.txtFile.Text)) { MessageBox.Show("文件不存在!"); return; } if (!Directory.Exists(this.txtFolder.Text)) { MessageBox.Show("文件夾不存在!"); return; } string[] arrName = this.txtFile.Text.Split('\\'); string name = arrName[arrName.Length - 1]; //第三個參數(shù)true代表文件存在直接覆蓋 //如果希望不覆蓋,此處添加代碼判斷文件已經(jīng)存在給出提示 File.Copy(this.txtFile.Text, this.txtFolder.Text + "\\" + name,true); MessageBox.Show("復(fù)制成功!"); } //移動文件 private void btMove_Click(object sender, EventArgs e) { if (!File.Exists(this.txtFile.Text)) { MessageBox.Show("文件不存在!"); return; } if (!Directory.Exists(this.txtFolder.Text)) { MessageBox.Show("文件夾不存在!"); return; } string[] arrName = this.txtFile.Text.Split('\\'); string name = arrName[arrName.Length - 1]; string newFileName = this.txtFolder.Text + "\\" + name; if (File.Exists(newFileName)) { //方案一:提示用戶有重名文件 //MessageBox.Show("目標(biāo)位置有重名文件!"); //return; //方案二:直接將目標(biāo)文件刪除 File.Delete(newFileName); } File.Move(this.txtFile.Text, newFileName); MessageBox.Show("移動成功!"); } //刪除文件 private void btDelete_Click(object sender, EventArgs e) { if (!File.Exists(this.txtFile.Text)) { MessageBox.Show("文件不存在!"); return; } File.Delete(this.txtFile.Text); MessageBox.Show("刪除成功!"); }
和FileInfo類相比,使用File類可以避免頻繁創(chuàng)建和釋放對象的系統(tǒng)開銷,但如果需要多次重用某個文件對象,則使用FileInfo類。
下面使用FileInfo類實現(xiàn)相同功能,代碼如下:
//選擇文件按鈕 private void btOpenFile_Click(object sender, EventArgs e) { if (this.openFileDialog1.ShowDialog() == DialogResult.OK) { //FileName包含路徑,SafeFileName不包含路徑 this.txtFile.Text = this.openFileDialog1.FileName; } } //選擇文件夾按鈕 private void btOpenFolder_Click(object sender, EventArgs e) { if (this.folderBrowserDialog1.ShowDialog() == DialogResult.OK) { this.txtFolder.Text = this.folderBrowserDialog1.SelectedPath; } } //復(fù)制文件 private void btCopy_Click(object sender, EventArgs e) { FileInfo fInfo = new FileInfo(this.txtFile.Text); if (fInfo.Exists == false) { MessageBox.Show("文件不存在!"); return; } DirectoryInfo dInfo = new DirectoryInfo(this.txtFolder.Text); if (dInfo.Exists == false) { MessageBox.Show("文件夾不存在!"); return; } string[] arrName = this.txtFile.Text.Split('\\'); string name = arrName[arrName.Length - 1]; //第二個參數(shù)true代表文件存在直接覆蓋 fInfo.CopyTo(this.txtFolder.Text + "\\" + name, true); MessageBox.Show("復(fù)制成功!"); } //移動文件 private void btMove_Click(object sender, EventArgs e) { FileInfo fInfo = new FileInfo(this.txtFile.Text); if (fInfo.Exists == false) { MessageBox.Show("文件不存在!"); return; } DirectoryInfo dInfo = new DirectoryInfo(this.txtFolder.Text); if (dInfo.Exists == false) { MessageBox.Show("文件夾不存在!"); return; } string[] arrName = this.txtFile.Text.Split('\\'); string name = arrName[arrName.Length - 1]; string newFileName = this.txtFolder.Text + "\\" + name; FileInfo deskFile = new FileInfo(newFileName); if (deskFile.Exists == true) { //方案一:提示用戶有重名文件 //MessageBox.Show("目標(biāo)位置有重名文件!"); //return; //方案二:直接將目標(biāo)文件刪除 deskFile.Delete(); } fInfo.MoveTo(newFileName); MessageBox.Show("移動成功!"); } //刪除文件 private void btDelete_Click(object sender, EventArgs e) { FileInfo fInfo = new FileInfo(this.txtFile.Text); if (fInfo.Exists == false) { MessageBox.Show("文件不存在!"); return; } fInfo.Delete(); MessageBox.Show("刪除成功!"); }
(2)文件夾常用操作
Directory類是靜態(tài)類,其中所有方法都是靜態(tài)的,通過類名直接調(diào)用。
示例,如下圖,進(jìn)行文件夾的基本操作:
點擊"選擇文件夾一"按鈕,選擇文件夾,并把文件夾路徑顯示在第一個文本框。
點擊"選擇文件夾二"按鈕,選擇文件夾,并把文件夾路徑顯示在第二個文本框。
點擊"移動文件夾"按鈕,將第一個文本框路徑的文件夾移動到第二個文本框路徑的文件夾下。
點擊"刪除文件夾"按鈕,將第一個文本框路徑的文件夾進(jìn)行刪除。
其中"選擇文件夾一"按鈕name=btOpen1,"選擇文件夾二"按鈕name=btOpen2,"移動文件夾"按鈕name=btMove,"刪除文件夾"按鈕name=btDelete。
第一個文本框name=txtFolder1,第二個文本框name=txtFolder2。
文件對話框name=openFileDialog1,文件夾對話框name=folderBrowserDialog1。
Directory實現(xiàn)代碼如下:
//選擇文件夾一 private void btOpen1_Click(object sender, EventArgs e) { if (this.folderBrowserDialog1.ShowDialog() == DialogResult.OK) { this.txtFolder1.Text = this.folderBrowserDialog1.SelectedPath; } } //選擇文件夾二 private void btOpen2_Click(object sender, EventArgs e) { if (this.folderBrowserDialog1.ShowDialog() == DialogResult.OK) { this.txtFolder2.Text = this.folderBrowserDialog1.SelectedPath; } } //移動文件夾 private void btMove_Click(object sender, EventArgs e) { if (!Directory.Exists(this.txtFolder1.Text) || !Directory.Exists(this.txtFolder2.Text)) { MessageBox.Show("文件夾不存在!"); return; } //獲取文件夾名稱 string[] arrFolderName = this.txtFolder1.Text.Split('\\'); string folderName = arrFolderName[arrFolderName.Length - 1]; string newFolderName = this.txtFolder2.Text + "\\" + folderName; //判斷目標(biāo)地址是否已經(jīng)有該文件夾了 if (Directory.Exists(newFolderName)) { //方案一:給出提示 //MessageBox.Show("在目標(biāo)位置,該文件夾已經(jīng)存在了"); //return; //方案二:刪除目標(biāo)位置的文件夾 Directory.Delete(newFolderName,true); } //此移動操作只能在同一個根盤符上操作 Directory.Move(this.txtFolder1.Text, newFolderName); MessageBox.Show("移動文件夾成功!"); } private void btDelete_Click(object sender, EventArgs e) { if (!Directory.Exists(this.txtFolder1.Text)) { MessageBox.Show("文件夾不存在!"); return; } //第二個參數(shù)代表刪除所有的子文件夾和文件 Directory.Delete(this.txtFolder1.Text, true); MessageBox.Show("刪除文件夾成功!"); }
同樣上述功能,使用DirectoryInfo實現(xiàn)如下:
//選擇文件夾一 private void btOpen1_Click(object sender, EventArgs e) { if (this.folderBrowserDialog1.ShowDialog() == DialogResult.OK) { this.txtFolder1.Text = this.folderBrowserDialog1.SelectedPath; } } //選擇文件夾二 private void btOpen2_Click(object sender, EventArgs e) { if (this.folderBrowserDialog1.ShowDialog() == DialogResult.OK) { this.txtFolder2.Text = this.folderBrowserDialog1.SelectedPath; } } //移動文件夾 private void btMove_Click(object sender, EventArgs e) { DirectoryInfo startInfo = new DirectoryInfo(this.txtFolder1.Text); DirectoryInfo endInfo = new DirectoryInfo(this.txtFolder2.Text); if (startInfo.Exists == false || endInfo.Exists == false) { MessageBox.Show("文件夾不存在"); return; } string[] arrFolderName = this.txtFolder1.Text.Split('\\'); string folderName = arrFolderName[arrFolderName.Length - 1]; string newFolderName = this.txtFolder2.Text + "\\" + folderName; //判斷目標(biāo)地址是否已經(jīng)有該文件夾了 DirectoryInfo tmp = new DirectoryInfo(newFolderName); if (tmp.Exists == true) { //方案一:給出提示 //MessageBox.Show("在目標(biāo)位置,該文件夾已經(jīng)存在了"); //return; //方案二:刪除目標(biāo)位置的文件夾 tmp.Delete(true); } //此移動操作只能在同一個根盤符上操作 startInfo.MoveTo(newFolderName); MessageBox.Show("移動成功!"); } private void btDelete_Click(object sender, EventArgs e) { DirectoryInfo startInfo = new DirectoryInfo(this.txtFolder1.Text); if (startInfo.Exists == false) { MessageBox.Show("文件夾不存在"); return; } //參數(shù)代表刪除所有的子文件夾和文件 startInfo.Delete(true); MessageBox.Show("刪除文件夾成功!"); }
(3)文件夾的復(fù)制和移動
關(guān)于文件夾的移動,系統(tǒng)提供給我們的功能,只能在同一個根盤符上操作。
關(guān)于文件夾的復(fù)制,系統(tǒng)根本就沒有提供相應(yīng)的API。
所以關(guān)于文件夾的復(fù)制以及文件移動跨磁盤只能自己寫,自己實現(xiàn)了,如圖:
點擊"選擇文件夾一"按鈕:可以選擇一個文件夾,并且將文件夾的路徑顯示在第一個文本框。
點擊"選擇文件夾二"按鈕:可以選擇一個文件夾,并且將文件夾的路徑顯示在第二個文本框。
點擊"復(fù)制文件夾"按鈕:將第一個文件夾及文件夾內(nèi)容復(fù)制到第二個文件夾中。
點擊"移動文件夾"按鈕:將第一個文件夾及文件夾內(nèi)容移動到第二個文件夾中。
其中:"選擇文件夾一"按鈕name=btOpen1,"選擇文件夾二"按鈕name=btOpen2,"復(fù)制文件夾"按鈕name=btCopy,"移動文件夾"按鈕name=btMove。
第一個文本框name=txtFolder1,第二個文本框name=txtFolder2。
文件對話框name=openFileDialog1,文件夾對話框name=folderBrowserDialog1。
具體實現(xiàn)代碼如下:
編寫通用的遞歸方法,實現(xiàn)文件夾的復(fù)制:
//endFolderPath為處理之后的目標(biāo)路徑 //例如將"C:\abc"復(fù)制到"D:123\",endFolderPath需要傳遞處理之后的"D:123\abc" private void CopyFolder(string startFolderPath, string endFolderPath) { //在創(chuàng)建目標(biāo)文件夾 Directory.CreateDirectory(endFolderPath); DirectoryInfo startDir = new DirectoryInfo(startFolderPath); //循環(huán)復(fù)制文件夾下的所有文件 foreach (FileInfo item in startDir.GetFiles()) { File.Copy(item.FullName, endFolderPath + "\\" + item.Name); } //循環(huán)所有子文件夾形成遞歸調(diào)用 foreach (DirectoryInfo item in startDir.GetDirectories()) { string startPath = item.FullName; string newFolderName = endFolderPath + "\\" + item.Name; CopyFolder(startPath, newFolderName); } }
各個按鈕的代碼如下:
private void btOpen1_Click(object sender, EventArgs e) { if (this.folderBrowserDialog1.ShowDialog() == DialogResult.OK) { this.txtFolder1.Text = this.folderBrowserDialog1.SelectedPath; } } private void btOpen2_Click(object sender, EventArgs e) { if (this.folderBrowserDialog1.ShowDialog() == DialogResult.OK) { this.txtFolder2.Text = this.folderBrowserDialog1.SelectedPath; } } //復(fù)制文件夾 private void btCopy_Click(object sender, EventArgs e) { if (!Directory.Exists(this.txtFolder1.Text) || !Directory.Exists(this.txtFolder2.Text)) { MessageBox.Show("文件夾不存在!"); return; } string[] arrFolderName = this.txtFolder1.Text.Split('\\'); string folderName = arrFolderName[arrFolderName.Length - 1]; string newFolderName = this.txtFolder2.Text + "\\" + folderName; //判斷目標(biāo)地址是否已經(jīng)有該文件夾了 if (Directory.Exists(newFolderName)) { //方案一:給出提示 //MessageBox.Show("在目標(biāo)位置,該文件夾已經(jīng)存在了"); //return; //方案二:刪除目標(biāo)位置的文件夾 Directory.Delete(newFolderName, true); } CopyFolder(this.txtFolder1.Text, newFolderName); MessageBox.Show("復(fù)制成功!"); } //移動文件夾 private void btMove_Click(object sender, EventArgs e) { if (!Directory.Exists(this.txtFolder1.Text) || !Directory.Exists(this.txtFolder2.Text)) { MessageBox.Show("文件夾不存在!"); return; } string[] arrFolderName = this.txtFolder1.Text.Split('\\'); string folderName = arrFolderName[arrFolderName.Length - 1]; string newFolderName = this.txtFolder2.Text + "\\" + folderName; //判斷目標(biāo)地址是否已經(jīng)有該文件夾了 if (Directory.Exists(newFolderName)) { //方案一:給出提示 //MessageBox.Show("在目標(biāo)位置,該文件夾已經(jīng)存在了"); //return; //方案二:刪除目標(biāo)位置的文件夾 Directory.Delete(newFolderName, true); } CopyFolder(this.txtFolder1.Text, newFolderName); //復(fù)制完成后,刪除原始位置的文件夾 Directory.Delete(this.txtFolder1.Text, true); MessageBox.Show("移動成功!"); }
三、讀寫文本文件
文件和流的概念:
--文件是在各種媒質(zhì)上永久存儲的數(shù)據(jù)的有序集合。它是進(jìn)行數(shù)據(jù)讀寫操作的基本對象。
--流是一種向存儲器讀取和寫入字節(jié)的方式,也是進(jìn)行數(shù)據(jù)讀寫操作的基本對象。
--流提供了連續(xù)的字節(jié)流存儲空間,其實際存儲位置可以不連續(xù)。
--C#中所有表示流的類都繼承于抽象類Stream。
讀寫文本文件最常用的類有:
--FileStream(文件流)
--StreamReader(流讀取器)
--StreamWriter(流寫入器)
讀寫文件操作的基本步驟為:
- 創(chuàng)建文件流
- 創(chuàng)建讀、寫器
- 執(zhí)行讀、寫操作
- 關(guān)閉讀寫器
- 關(guān)閉文件流
文件流對象:
實例化文件流對象語法如下:
FileStream fs = new FileStream(FileName, FileMode,FileAccess);
其中FileMode的枚舉值如下:
值名稱 | 功能說明 |
---|---|
CreateNew | 創(chuàng)建新文件,如果文件已存在則引發(fā)異常 |
Create | 創(chuàng)建新文件,如果文件已存在則覆蓋 |
Open | 打開文件,如果文件不存在則引發(fā)異常 |
OpenOrCreate | 打開文件,如果文件不存在則創(chuàng)建新文件 |
Append | 打開文件并查找到文件尾,如果文件不存在則創(chuàng)建新文件 |
Truncate | 打開現(xiàn)在文件并清除其內(nèi)容,如果文件不存在則引發(fā)異常 |
其中FileAccess的枚舉值如下:
值名稱 | 功能說明 |
---|---|
Read | 對文件進(jìn)行只讀訪問 |
Write | 對文件進(jìn)行只寫訪問 |
ReadWrite | 對文件進(jìn)行讀寫訪問 |
文件讀寫器常用方法:
StreamReader的常用方法:
值名稱 | 功能說明 |
---|---|
Read | 讀取輸入流中的下一個(組)字符 |
ReadLine | 讀取當(dāng)前流中的一行字符,并將數(shù)據(jù)作為字符串返回 |
ReadToEnd | 讀取從當(dāng)前位置到末尾的所有字符,并將數(shù)據(jù)作為字符串返回 |
Close | 關(guān)閉StreamReader對象和基礎(chǔ)流,并釋放與讀取器關(guān)聯(lián)的所有系統(tǒng)資源 |
StreamWriter的常用方法:
值名稱 | 功能說明 |
---|---|
Write | 將數(shù)據(jù)寫入流 |
WriteLine | 將行結(jié)束符之前的數(shù)據(jù)寫入流 |
Close | 關(guān)閉StreamWriter對象和基礎(chǔ)流 |
示例:如下圖,編寫一個文本文件讀寫器
--點擊"打開文件"按鈕,選擇一個文本文件,并且將文本文件路徑顯示在上面單行文本框中,將文本文件的內(nèi)容顯示在下面的多行文本框中。
--多行文本框,可以進(jìn)行修改其文本內(nèi)容。
--點擊"保存文件"按鈕,將多行文本框的文本保存到打開的文本文件中。
其中"打開文件"按鈕name=btOpen,"保存文件"按鈕name=btSave,單行文本框name=txtFilePath,多行文本框name=txtContent。
實現(xiàn)代碼如下:
private void btOpen_Click(object sender, EventArgs e) { OpenFileDialog dialog = new OpenFileDialog(); DialogResult result = dialog.ShowDialog(); //點擊打開按鈕之后 if (result == System.Windows.Forms.DialogResult.OK) { this.txtFilePath.Text = dialog.FileName; } else { return; } //方案一:使用Filestream將文本一次性全部轉(zhuǎn)換為字節(jié)數(shù)組,之后轉(zhuǎn)換為string //FileStream fs = new FileStream(this.txtFilePath.Text, FileMode.Open, FileAccess.Read); ////fs.Seek(0, SeekOrigin.Begin); //定位流,從開始位置移動0個字節(jié),也就是流的最開始位置 //int len = (int)fs.Length; //獲取文件的字節(jié)長度 //byte[] arrByte = new byte[len]; //定義字節(jié)數(shù)組 //fs.Read(arrByte, 0, arrByte.Length); //將文件流讀入字節(jié)數(shù)組 //this.txtContent.Text = Encoding.Default.GetString(arrByte,0,len); //fs.Close(); //方案二:使用Filestream,逐字節(jié)讀取文本,后將字節(jié)轉(zhuǎn)換為string //FileStream fs = new FileStream(this.txtFilePath.Text, FileMode.Open, FileAccess.Read); //int len = (int)fs.Length; //獲取文件的字節(jié)長度 //byte[] arrByte = new byte[len]; //定義字節(jié)數(shù)組 //int index = 0; //保存字節(jié)數(shù)組變化的下標(biāo) //int code = fs.ReadByte(); //讀取一個字節(jié) //while (code != -1) //讀取內(nèi)容等于-1即表示讀取完畢 //{ // //將讀取內(nèi)容轉(zhuǎn)換成字節(jié)存入數(shù)組 // arrByte[index] = Convert.ToByte(code); // code = fs.ReadByte(); //繼續(xù)逐字節(jié)讀取 // index++; //} //this.txtContent.Text = Encoding.Default.GetString(arrByte, 0, len); //fs.Close(); //方案三:直接使用File的Read All Text 函數(shù)將文本文件內(nèi)容全部讀入text //File.ReadAllBytes可以讀取成字節(jié)數(shù)組 //this.txtContent.Text = File.ReadAllText(this.txtFilePath.Text, Encoding.Default); //方案四:使用StreamReader流讀取器讀取 FileStream fs = new FileStream(this.txtFilePath.Text, FileMode.Open, FileAccess.Read); StreamReader sd = new StreamReader(fs, Encoding.Default); //這里可以逐行讀入 //string line = sd.ReadLine(); //while (line != null) //{ // this.txtContent.Text = this.txtContent.Text + line + "\r\n"; // line = sd.ReadLine(); //} //也可以全部讀入 this.txtContent.Text = sd.ReadToEnd(); sd.Close(); fs.Close(); } private void btSave_Click(object sender, EventArgs e) { //方案一:File類靜態(tài)方法 //File.WriteAllText(this.txtFileName.Text, this.txtContent.Text,Encoding.Default); //MessageBox.Show("保存成功!"); //方案二:使用StreamWriter流寫入器 FileStream fs = new FileStream(this.txtFileName.Text, FileMode.Open, FileAccess.Write); StreamWriter sw = new StreamWriter(fs, Encoding.Default); sw.Write(this.txtContent.Text); sw.Close(); fs.Close(); MessageBox.Show("保存成功!"); }
四、序列化與反序列化
序列化就是將對象實例的狀態(tài)存儲到存儲媒介的過程。
序列化和反序列化的實現(xiàn)步驟(二進(jìn)制序列化):
- (1)引入System.Runtime.Serialization.Formatters.Binary命名空間
- (2)要序列化的對象需要標(biāo)記Serializable特性
- (3)其父類和屬性中的引用類型也標(biāo)記Serializable特性
- (4)使用BinaryFormatter 對象的Serialize()方法和Deserialize()方法
(1)序列化單個對象
示例:如下圖,實現(xiàn)單個對象的序列化與反序列化
--輸入學(xué)生信息,點擊"保存信息"按鈕,將學(xué)生信息永久序列化保存到電腦上。
--關(guān)閉程序后,在啟動程序,可以將本地序列化文件讀取,將信息顯示在界面的文本框中。
其中,學(xué)號,姓名,年齡文本框的name分別為txtNo,txtName,txtAge。
保存信息和讀取信息按鈕name分別為btSave和btRead。
具體實現(xiàn)代碼如下:
定義一個學(xué)生類:
[Serializable] class Student { public string StuNo { get; set; } //學(xué)號 public string StuName { get; set; } //姓名 public int StuAge { get; set; } //年齡 }
其中[Serializable]關(guān)鍵字代表此類是可以被序列化的。
編寫按鈕響應(yīng)事件代碼:
private void btSave_Click(object sender, EventArgs e) { Student stu = new Student(); stu.StuNo = this.txtNo.Text; stu.StuName = this.txtName.Text; stu.StuAge = int.Parse(this.txtAge.Text); FileStream fs = new FileStream("stu.ini", FileMode.Create, FileAccess.ReadWrite); BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(fs, stu); //序列化 fs.Close(); MessageBox.Show("保存成功!"); } private void btRead_Click(object sender, EventArgs e) { FileStream fs = new FileStream("stu.ini", FileMode.Open, FileAccess.ReadWrite); BinaryFormatter bf = new BinaryFormatter(); Student stu = bf.Deserialize(fs) as Student; //反序列化 this.txtNo.Text = stu.StuNo; this.txtName.Text = stu.StuName; this.txtAge.Text = stu.StuAge.ToString(); fs.Close(); }
(2)序列化集合
示例:如下圖,實現(xiàn)集合的序列化
--打開窗體,自動從序列化文件中讀取信息,并在listView列表上進(jìn)行展示。
--輸入學(xué)生信息,點擊"添加信息"按鈕,添加學(xué)生,并且序列化學(xué)生列表,刷新ListView列表數(shù)據(jù)。
其中展示列表的ListView控件的name=listView1。
學(xué)號,姓名,年齡文本框的name分別為txtNo,txtName,txtAge。
添加信息按鈕name=btSave。
具體實現(xiàn)代碼如下:
定義一個學(xué)生類:
[Serializable] class Student { public string StuNo { get; set; } //學(xué)號 public string StuName { get; set; } //姓名 public int StuAge { get; set; } //年齡 }
其中[Serializable]關(guān)鍵字代表此類是可以被序列化的。
編寫按鈕響應(yīng)事件代碼:
List<Student> list = new List<Student>(); private void BindData() { if (!File.Exists("list.ini")) return; //讀取序列化文件 FileStream fs = new FileStream("list.ini", FileMode.Open, FileAccess.ReadWrite); BinaryFormatter bf = new BinaryFormatter(); list = bf.Deserialize(fs) as List<Student>; //反序列化 fs.Close(); //將list集合數(shù)據(jù)綁定到ListView控件 this.listView1.Items.Clear(); foreach (Student stu in list) { ListViewItem item = new ListViewItem(stu.StuNo); item.SubItems.Add(stu.StuName); item.SubItems.Add(stu.StuAge.ToString()); this.listView1.Items.Add(item); } } private void Form2_Load(object sender, EventArgs e) { BindData(); } private void btSave_Click(object sender, EventArgs e) { Student stu = new Student(); stu.StuNo = this.txtNo.Text; stu.StuName = this.txtName.Text; stu.StuAge = int.Parse(this.txtAge.Text); list.Add(stu); FileStream fs = new FileStream("list.ini", FileMode.Create, FileAccess.ReadWrite); BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(fs, list); //序列化 fs.Close(); MessageBox.Show("保存成功!"); BindData(); }
到此這篇關(guān)于C#開發(fā)Winform實現(xiàn)文件操作案例的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#通過cmd調(diào)用7z軟件實現(xiàn)壓縮和解壓文件
這篇文章介紹了C#通過cmd調(diào)用7z軟件實現(xiàn)壓縮和解壓文件的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-04-04C#對稱加密(AES加密)每次生成的結(jié)果都不同的實現(xiàn)思路和代碼實例
這篇文章主要介紹了C#對稱加密(AES加密)每次生成的結(jié)果都不同的實現(xiàn)思路和代碼實例,每次解密時從密文中截取前16位,這就是實現(xiàn)隨機的奧秘,本文同時給出了實現(xiàn)代碼,需要的朋友可以參考下2015-07-07