C#開(kāi)發(fā)Winform實(shí)現(xiàn)文件操作案例
一、文件對(duì)話框
C#中共有三種文件對(duì)話框,分別用于不同的功能:
- (1)用于打開(kāi)文件的對(duì)話框OpenFileDialog。
- (2)用于保存文件的對(duì)話框SaveFileDialog。
- (3)打開(kāi)文件夾的對(duì)話框FolderBroswerDialog。
示例:如下圖,點(diǎn)擊三個(gè)按鈕分別彈出三種對(duì)話框,進(jìn)行相應(yīng)操作之后,將路徑在文本框中顯示:

(1)OpenFileDialog對(duì)話框
修改OpenFileDialog對(duì)話框的Name屬性為ofDlg。在“打開(kāi)”按鈕添加ofDlg.ShowDialog(); 界面如下:

通過(guò)ShowDialog()的返回值,判斷點(diǎn)擊的是“打開(kāi)”還是“取消”。在“打開(kāi)”按鈕點(diǎn)擊事件中編寫如下代碼:
private void btnOpen_Click(object sender, EventArgs e)
{
//判斷是否點(diǎn)擊的“打開(kāi)”按鈕
if (ofDlg.ShowDialog() == DialogResult.OK)
{
txtPath.Text = ofDlg.FileName;
}
}OpenFileDialog常用屬性表:
| 屬性名 | 功能說(shuō)明 |
|---|---|
| InitialDirectory | 對(duì)話框的初始目錄 |
| Filter | 文件篩選器,按"顯示名稱|類型"格式編寫 例如,"文本文件(.txt)|.txt|所有文件(.)||." |
| FilterIndex | 在對(duì)話框中選擇的文件篩選器的索引,如果選第一項(xiàng)就設(shè)為1 |
| FileName | 第一個(gè)在對(duì)話框中顯示的文件或最后一個(gè)選取的文件 |
| Title | 將顯示在對(duì)話框標(biāo)題欄中的字符 |
| CheckFileExists | 在用戶指定不存在的文件時(shí)是否顯示警告 |
| CheckPathExists | 在對(duì)話框返回之前,檢查指定路徑是否存在 |
(2)SaveFileDialog對(duì)話框
保存文件對(duì)話框常用于軟件中的“另存為”功能。其常用屬性、方法及使用方式與打開(kāi)文件對(duì)話框相同。
設(shè)置保存文件對(duì)話框的Filter屬性為“文本文件|*.txt”。在“保存”按鈕的點(diǎn)擊事件中編寫如下代碼:
private void btnSave_Click(object sender, EventArgs e)
{
if (sfDlg.ShowDialog() == DialogResult.OK)
{
txtPath.Text = sfDlg.FileName;
}
}(3)FolderBroswerDialog對(duì)話框
瀏覽文件夾對(duì)話框常用于瀏覽文件夾,選擇文件夾路徑。
在“瀏覽”按鈕的點(diǎn)擊事件中編寫如下代碼:
private void btnBrowse_Click(object sender, EventArgs e)
{
if (fbDlg.ShowDialog() == DialogResult.OK)
{
txtPath.Text = fbDlg.SelectedPath;
}
}FolderBroswerDialog常用屬性:
| 屬性名 | 能說(shuō)明功 |
|---|---|
| Description | 顯示在對(duì)話框的樹視圖上方的字符串,用來(lái)指定顯示給用戶的指導(dǎo)信息 |
| RootFolder | 設(shè)置根文件夾位置 |
| SelectedPath | 對(duì)話框中最先選擇的文件夾或用戶最后選擇的文件夾完整路徑 |
| ShowNewFold | 對(duì)話框中是否包括“新建文件夾”按鈕 |
二、文件及文件夾操作
文件及文件夾管理是操作系統(tǒng)的重要組成部分,主要包括創(chuàng)建、移動(dòng)、復(fù)制和刪除等操作。
Directory類和DirectoryInfo類用于對(duì)磁盤和文件夾的操作管理。
File類和FileInfo類用于對(duì)文件進(jìn)行常用操作管理。
(1)文件常用操作
在C#中如果對(duì)文件進(jìn)行創(chuàng)建、復(fù)制和刪除等少量操作一般使用File類。
File類是靜態(tài)類,其中所有方法都是靜態(tài)的,通過(guò)類名直接調(diào)用,不需要實(shí)例化。
示例,如下圖,進(jìn)行文件的基本操作:

點(diǎn)擊"選擇文件"按鈕選擇某個(gè)文件,并將文件路徑在文本框顯示。
點(diǎn)擊"選擇文件夾"按鈕選擇某個(gè)文件夾,并將文件夾路徑在文本框顯示。
點(diǎn)擊"復(fù)制文件"按鈕,實(shí)現(xiàn)將文件復(fù)制到文件夾中。
點(diǎn)擊"移動(dòng)文件"按鈕,實(shí)現(xiàn)將文件移動(dòng)到文件夾中。
點(diǎn)擊"刪除文件"按鈕,實(shí)現(xiàn)將文件刪除。
其中,"選擇文件"按鈕name=btOpenFile,"選擇文件夾"按鈕name=btOpenFolder,"復(fù)制文件"按鈕name=btCopy,"移動(dòng)文件"按鈕name=btMove,"刪除文件"按鈕name=btDelete。
存放文件名的文本框name=txtFile,存放文件夾名的文本框name=txtFolder。
文件對(duì)話框name=openFileDialog1,文件夾對(duì)話框name=folderBrowserDialog1。
File類實(shí)現(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];
//第三個(gè)參數(shù)true代表文件存在直接覆蓋
//如果希望不覆蓋,此處添加代碼判斷文件已經(jīng)存在給出提示
File.Copy(this.txtFile.Text, this.txtFolder.Text + "\\" + name,true);
MessageBox.Show("復(fù)制成功!");
}
//移動(dòng)文件
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("移動(dòng)成功!");
}
//刪除文件
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)建和釋放對(duì)象的系統(tǒng)開(kāi)銷,但如果需要多次重用某個(gè)文件對(duì)象,則使用FileInfo類。
下面使用FileInfo類實(shí)現(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];
//第二個(gè)參數(shù)true代表文件存在直接覆蓋
fInfo.CopyTo(this.txtFolder.Text + "\\" + name, true);
MessageBox.Show("復(fù)制成功!");
}
//移動(dòng)文件
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("移動(dòng)成功!");
}
//刪除文件
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)的,通過(guò)類名直接調(diào)用。
示例,如下圖,進(jìn)行文件夾的基本操作:

點(diǎn)擊"選擇文件夾一"按鈕,選擇文件夾,并把文件夾路徑顯示在第一個(gè)文本框。
點(diǎn)擊"選擇文件夾二"按鈕,選擇文件夾,并把文件夾路徑顯示在第二個(gè)文本框。
點(diǎn)擊"移動(dòng)文件夾"按鈕,將第一個(gè)文本框路徑的文件夾移動(dòng)到第二個(gè)文本框路徑的文件夾下。
點(diǎn)擊"刪除文件夾"按鈕,將第一個(gè)文本框路徑的文件夾進(jìn)行刪除。
其中"選擇文件夾一"按鈕name=btOpen1,"選擇文件夾二"按鈕name=btOpen2,"移動(dòng)文件夾"按鈕name=btMove,"刪除文件夾"按鈕name=btDelete。
第一個(gè)文本框name=txtFolder1,第二個(gè)文本框name=txtFolder2。
文件對(duì)話框name=openFileDialog1,文件夾對(duì)話框name=folderBrowserDialog1。
Directory實(shí)現(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;
}
}
//移動(dòng)文件夾
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);
}
//此移動(dòng)操作只能在同一個(gè)根盤符上操作
Directory.Move(this.txtFolder1.Text, newFolderName);
MessageBox.Show("移動(dòng)文件夾成功!");
}
private void btDelete_Click(object sender, EventArgs e)
{
if (!Directory.Exists(this.txtFolder1.Text))
{
MessageBox.Show("文件夾不存在!");
return;
}
//第二個(gè)參數(shù)代表刪除所有的子文件夾和文件
Directory.Delete(this.txtFolder1.Text, true);
MessageBox.Show("刪除文件夾成功!");
}同樣上述功能,使用DirectoryInfo實(shí)現(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;
}
}
//移動(dòng)文件夾
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);
}
//此移動(dòng)操作只能在同一個(gè)根盤符上操作
startInfo.MoveTo(newFolderName);
MessageBox.Show("移動(dòng)成功!");
}
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ù)制和移動(dòng)
關(guān)于文件夾的移動(dòng),系統(tǒng)提供給我們的功能,只能在同一個(gè)根盤符上操作。
關(guān)于文件夾的復(fù)制,系統(tǒng)根本就沒(méi)有提供相應(yīng)的API。
所以關(guān)于文件夾的復(fù)制以及文件移動(dòng)跨磁盤只能自己寫,自己實(shí)現(xiàn)了,如圖:

點(diǎn)擊"選擇文件夾一"按鈕:可以選擇一個(gè)文件夾,并且將文件夾的路徑顯示在第一個(gè)文本框。
點(diǎn)擊"選擇文件夾二"按鈕:可以選擇一個(gè)文件夾,并且將文件夾的路徑顯示在第二個(gè)文本框。
點(diǎn)擊"復(fù)制文件夾"按鈕:將第一個(gè)文件夾及文件夾內(nèi)容復(fù)制到第二個(gè)文件夾中。
點(diǎn)擊"移動(dòng)文件夾"按鈕:將第一個(gè)文件夾及文件夾內(nèi)容移動(dòng)到第二個(gè)文件夾中。
其中:"選擇文件夾一"按鈕name=btOpen1,"選擇文件夾二"按鈕name=btOpen2,"復(fù)制文件夾"按鈕name=btCopy,"移動(dòng)文件夾"按鈕name=btMove。
第一個(gè)文本框name=txtFolder1,第二個(gè)文本框name=txtFolder2。
文件對(duì)話框name=openFileDialog1,文件夾對(duì)話框name=folderBrowserDialog1。
具體實(shí)現(xiàn)代碼如下:
編寫通用的遞歸方法,實(shí)現(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);
}
}各個(gè)按鈕的代碼如下:
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ù)制成功!");
}
//移動(dòng)文件夾
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("移動(dòng)成功!");
}三、讀寫文本文件
文件和流的概念:
--文件是在各種媒質(zhì)上永久存儲(chǔ)的數(shù)據(jù)的有序集合。它是進(jìn)行數(shù)據(jù)讀寫操作的基本對(duì)象。
--流是一種向存儲(chǔ)器讀取和寫入字節(jié)的方式,也是進(jìn)行數(shù)據(jù)讀寫操作的基本對(duì)象。
--流提供了連續(xù)的字節(jié)流存儲(chǔ)空間,其實(shí)際存儲(chǔ)位置可以不連續(xù)。
--C#中所有表示流的類都繼承于抽象類Stream。
讀寫文本文件最常用的類有:
--FileStream(文件流)
--StreamReader(流讀取器)
--StreamWriter(流寫入器)
讀寫文件操作的基本步驟為:
- 創(chuàng)建文件流
- 創(chuàng)建讀、寫器
- 執(zhí)行讀、寫操作
- 關(guān)閉讀寫器
- 關(guān)閉文件流
文件流對(duì)象:
實(shí)例化文件流對(duì)象語(yǔ)法如下:
FileStream fs = new FileStream(FileName, FileMode,FileAccess);
其中FileMode的枚舉值如下:
| 值名稱 | 功能說(shuō)明 |
|---|---|
| CreateNew | 創(chuàng)建新文件,如果文件已存在則引發(fā)異常 |
| Create | 創(chuàng)建新文件,如果文件已存在則覆蓋 |
| Open | 打開(kāi)文件,如果文件不存在則引發(fā)異常 |
| OpenOrCreate | 打開(kāi)文件,如果文件不存在則創(chuàng)建新文件 |
| Append | 打開(kāi)文件并查找到文件尾,如果文件不存在則創(chuàng)建新文件 |
| Truncate | 打開(kāi)現(xiàn)在文件并清除其內(nèi)容,如果文件不存在則引發(fā)異常 |
其中FileAccess的枚舉值如下:
| 值名稱 | 功能說(shuō)明 |
|---|---|
| Read | 對(duì)文件進(jìn)行只讀訪問(wèn) |
| Write | 對(duì)文件進(jìn)行只寫訪問(wèn) |
| ReadWrite | 對(duì)文件進(jìn)行讀寫訪問(wèn) |
文件讀寫器常用方法:
StreamReader的常用方法:
| 值名稱 | 功能說(shuō)明 |
|---|---|
| Read | 讀取輸入流中的下一個(gè)(組)字符 |
| ReadLine | 讀取當(dāng)前流中的一行字符,并將數(shù)據(jù)作為字符串返回 |
| ReadToEnd | 讀取從當(dāng)前位置到末尾的所有字符,并將數(shù)據(jù)作為字符串返回 |
| Close | 關(guān)閉StreamReader對(duì)象和基礎(chǔ)流,并釋放與讀取器關(guān)聯(lián)的所有系統(tǒng)資源 |
StreamWriter的常用方法:
| 值名稱 | 功能說(shuō)明 |
|---|---|
| Write | 將數(shù)據(jù)寫入流 |
| WriteLine | 將行結(jié)束符之前的數(shù)據(jù)寫入流 |
| Close | 關(guān)閉StreamWriter對(duì)象和基礎(chǔ)流 |
示例:如下圖,編寫一個(gè)文本文件讀寫器

--點(diǎn)擊"打開(kāi)文件"按鈕,選擇一個(gè)文本文件,并且將文本文件路徑顯示在上面單行文本框中,將文本文件的內(nèi)容顯示在下面的多行文本框中。
--多行文本框,可以進(jìn)行修改其文本內(nèi)容。
--點(diǎn)擊"保存文件"按鈕,將多行文本框的文本保存到打開(kāi)的文本文件中。
其中"打開(kāi)文件"按鈕name=btOpen,"保存文件"按鈕name=btSave,單行文本框name=txtFilePath,多行文本框name=txtContent。
實(shí)現(xiàn)代碼如下:
private void btOpen_Click(object sender, EventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog();
DialogResult result = dialog.ShowDialog();
//點(diǎn)擊打開(kāi)按鈕之后
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); //定位流,從開(kāi)始位置移動(dòng)0個(gè)字節(jié),也就是流的最開(kāi)始位置
//int len = (int)fs.Length; //獲取文件的字節(jié)長(zhǎng)度
//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é)長(zhǎng)度
//byte[] arrByte = new byte[len]; //定義字節(jié)數(shù)組
//int index = 0; //保存字節(jié)數(shù)組變化的下標(biāo)
//int code = fs.ReadByte(); //讀取一個(gè)字節(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("保存成功!");
}四、序列化與反序列化
序列化就是將對(duì)象實(shí)例的狀態(tài)存儲(chǔ)到存儲(chǔ)媒介的過(guò)程。
序列化和反序列化的實(shí)現(xiàn)步驟(二進(jìn)制序列化):
- (1)引入System.Runtime.Serialization.Formatters.Binary命名空間
- (2)要序列化的對(duì)象需要標(biāo)記Serializable特性
- (3)其父類和屬性中的引用類型也標(biāo)記Serializable特性
- (4)使用BinaryFormatter 對(duì)象的Serialize()方法和Deserialize()方法
(1)序列化單個(gè)對(duì)象
示例:如下圖,實(shí)現(xiàn)單個(gè)對(duì)象的序列化與反序列化

--輸入學(xué)生信息,點(diǎn)擊"保存信息"按鈕,將學(xué)生信息永久序列化保存到電腦上。
--關(guān)閉程序后,在啟動(dòng)程序,可以將本地序列化文件讀取,將信息顯示在界面的文本框中。
其中,學(xué)號(hào),姓名,年齡文本框的name分別為txtNo,txtName,txtAge。
保存信息和讀取信息按鈕name分別為btSave和btRead。
具體實(shí)現(xiàn)代碼如下:
定義一個(gè)學(xué)生類:
[Serializable]
class Student
{
public string StuNo { get; set; } //學(xué)號(hào)
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)序列化集合
示例:如下圖,實(shí)現(xiàn)集合的序列化

--打開(kāi)窗體,自動(dòng)從序列化文件中讀取信息,并在listView列表上進(jìn)行展示。
--輸入學(xué)生信息,點(diǎn)擊"添加信息"按鈕,添加學(xué)生,并且序列化學(xué)生列表,刷新ListView列表數(shù)據(jù)。
其中展示列表的ListView控件的name=listView1。
學(xué)號(hào),姓名,年齡文本框的name分別為txtNo,txtName,txtAge。
添加信息按鈕name=btSave。
具體實(shí)現(xiàn)代碼如下:
定義一個(gè)學(xué)生類:
[Serializable]
class Student
{
public string StuNo { get; set; } //學(xué)號(hào)
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#開(kāi)發(fā)Winform實(shí)現(xiàn)文件操作案例的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Unity實(shí)現(xiàn)游戲卡牌滾動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)游戲卡牌滾動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-02-02
C#通過(guò)cmd調(diào)用7z軟件實(shí)現(xiàn)壓縮和解壓文件
這篇文章介紹了C#通過(guò)cmd調(diào)用7z軟件實(shí)現(xiàn)壓縮和解壓文件的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04
C#對(duì)稱加密(AES加密)每次生成的結(jié)果都不同的實(shí)現(xiàn)思路和代碼實(shí)例
這篇文章主要介紹了C#對(duì)稱加密(AES加密)每次生成的結(jié)果都不同的實(shí)現(xiàn)思路和代碼實(shí)例,每次解密時(shí)從密文中截取前16位,這就是實(shí)現(xiàn)隨機(jī)的奧秘,本文同時(shí)給出了實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-07-07
C#實(shí)現(xiàn)簡(jiǎn)單的RSA非對(duì)稱加密算法示例
這篇文章主要介紹了C#實(shí)現(xiàn)簡(jiǎn)單的RSA非對(duì)稱加密算法,結(jié)合實(shí)例形式分析了C#實(shí)現(xiàn)RSA加密的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下2017-08-08

