1. 程式人生 > 其它 >C#檔案操作案例

C#檔案操作案例

一、檔案對話方塊

C#中共有三種檔案對話方塊,分別用於不同的功能:

(1)用於開啟檔案的對話方塊OpenFileDialog。

(2)用於儲存檔案的對話方塊SaveFileDialog。

(3)開啟資料夾的對話方塊FolderBroswerDialog。

示例:如下圖,點選三個按鈕分別彈出三種對話方塊,進行相應操作之後,將路徑在文字框中顯示:

(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 在對話方塊中選擇的檔案篩選器的索引,如果選第一項就設為1
FileName 第一個在對話方塊中顯示的檔案或最後一個選取的檔案
Title 將顯示在對話方塊標題欄中的字元
CheckFileExists 在使用者指定不存在的檔案時是否顯示警告
CheckPathExists 在對話方塊返回之前,檢查指定路徑是否存在

(2)SaveFileDialog對話方塊

儲存檔案對話方塊常用於軟體中的“另存為”功能。其常用屬性、方法及使用方式與開啟檔案對話方塊相同。

設定儲存檔案對話方塊的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 顯示在對話方塊的樹檢視上方的字串,用來指定顯示給使用者的指導資訊
RootFolder 設定根資料夾位置
SelectedPath 對話方塊中最先選擇的資料夾或使用者最後選擇的資料夾完整路徑
ShowNewFold 對話方塊中是否包括“新建資料夾”按鈕

二、檔案及資料夾操作

檔案及資料夾管理是作業系統的重要組成部分,主要包括建立、移動、複製和刪除等操作。

Directory類和DirectoryInfo類用於對磁碟和資料夾的操作管理。

File類和FileInfo類用於對檔案進行常用操作管理。

(1)檔案常用操作

在C#中如果對檔案進行建立、複製和刪除等少量操作一般使用File類。

File類是靜態類,其中所有方法都是靜態的,通過類名直接呼叫,不需要例項化。

示例,如下圖,進行檔案的基本操作:

點選"選擇檔案"按鈕選擇某個檔案,並將檔案路徑在文字框顯示。

點選"選擇資料夾"按鈕選擇某個資料夾,並將資料夾路徑在文字框顯示。

點選"複製檔案"按鈕,實現將檔案複製到資料夾中。

點選"移動檔案"按鈕,實現將檔案移動到資料夾中。

點選"刪除檔案"按鈕,實現將檔案刪除。

其中,"選擇檔案"按鈕name=btOpenFile,"選擇資料夾"按鈕name=btOpenFolder,"複製檔案"按鈕name=btCopy,"移動檔案"按鈕name=btMove,"刪除檔案"按鈕name=btDelete。

存放檔名的文字框name=txtFile,存放資料夾名的文字框name=txtFolder。

檔案對話方塊name=openFileDialog1,資料夾對話方塊name=folderBrowserDialog1。

File類實現程式碼如下:

//選擇檔案按鈕
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;
    }
}
//複製檔案按鈕
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];
    //第三個引數true代表檔案存在直接覆蓋
    //如果希望不覆蓋,此處新增程式碼判斷檔案已經存在給出提示
    File.Copy(this.txtFile.Text, this.txtFolder.Text + "\\" + name,true);
    MessageBox.Show("複製成功!");
}

//移動檔案
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("目標位置有重名檔案!");
        //return;

        //方案二:直接將目標檔案刪除
        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類可以避免頻繁建立和釋放物件的系統開銷,但如果需要多次重用某個檔案物件,則使用FileInfo類。

下面使用FileInfo類實現相同功能,程式碼如下:

//選擇檔案按鈕
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;
    }
}
//複製檔案
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];
    //第二個引數true代表檔案存在直接覆蓋
    fInfo.CopyTo(this.txtFolder.Text + "\\" + name, true);
    MessageBox.Show("複製成功!");
}
//移動檔案
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("目標位置有重名檔案!");
        //return;

        //方案二:直接將目標檔案刪除
        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類是靜態類,其中所有方法都是靜態的,通過類名直接呼叫。

示例,如下圖,進行資料夾的基本操作:

![image](https://img2022.cnblogs.com/blog/1913282/202203/1913282-20220304223703329-690045863.png

點選"選擇資料夾一"按鈕,選擇資料夾,並把資料夾路徑顯示在第一個文字框。

點選"選擇資料夾二"按鈕,選擇資料夾,並把資料夾路徑顯示在第二個文字框。

點選"移動資料夾"按鈕,將第一個文字框路徑的資料夾移動到第二個文字框路徑的資料夾下。

點選"刪除資料夾"按鈕,將第一個文字框路徑的資料夾進行刪除。

其中"選擇資料夾一"按鈕name=btOpen1,"選擇資料夾二"按鈕name=btOpen2,"移動資料夾"按鈕name=btMove,"刪除資料夾"按鈕name=btDelete。

第一個文字框name=txtFolder1,第二個文字框name=txtFolder2。

檔案對話方塊name=openFileDialog1,資料夾對話方塊name=folderBrowserDialog1。

Directory實現程式碼如下:

//選擇資料夾一
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;
    //判斷目標地址是否已經有該檔案夾了
    if (Directory.Exists(newFolderName))
    {
        //方案一:給出提示
        //MessageBox.Show("在目標位置,該資料夾已經存在了");
        //return;

        //方案二:刪除目標位置的資料夾
        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;
    }
    //第二個引數代表刪除所有的子資料夾和檔案
    Directory.Delete(this.txtFolder1.Text, true);
    MessageBox.Show("刪除資料夾成功!");
}

同樣上述功能,使用DirectoryInfo實現如下:

//選擇資料夾一
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;
    //判斷目標地址是否已經有該檔案夾了
    DirectoryInfo tmp = new DirectoryInfo(newFolderName);
    if (tmp.Exists == true)
    {
        //方案一:給出提示
        //MessageBox.Show("在目標位置,該資料夾已經存在了");
        //return;
        //方案二:刪除目標位置的資料夾
        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;
    }
    //引數代表刪除所有的子資料夾和檔案
    startInfo.Delete(true);
    MessageBox.Show("刪除資料夾成功!");
}

(3)資料夾的複製和移動

關於資料夾的移動,系統提供給我們的功能,只能在同一個根碟符上操作。

關於資料夾的複製,系統根本就沒有提供相應的API。

所以關於資料夾的複製以及檔案移動跨磁碟只能自己寫,自己實現了,如圖:

點選"選擇資料夾一"按鈕:可以選擇一個資料夾,並且將資料夾的路徑顯示在第一個文字框。

點選"選擇資料夾二"按鈕:可以選擇一個資料夾,並且將資料夾的路徑顯示在第二個文字框。

點選"複製資料夾"按鈕:將第一個資料夾及資料夾內容複製到第二個資料夾中。

點選"移動資料夾"按鈕:將第一個資料夾及資料夾內容移動到第二個資料夾中。

其中:"選擇資料夾一"按鈕name=btOpen1,"選擇資料夾二"按鈕name=btOpen2,"複製資料夾"按鈕name=btCopy,"移動資料夾"按鈕name=btMove。

第一個文字框name=txtFolder1,第二個文字框name=txtFolder2。

檔案對話方塊name=openFileDialog1,資料夾對話方塊name=folderBrowserDialog1。

具體實現程式碼如下:

編寫通用的遞迴方法,實現資料夾的複製:

//endFolderPath為處理之後的目標路徑
//例如將"C:\abc"複製到"D:123\",endFolderPath需要傳遞處理之後的"D:123\abc"
private void CopyFolder(string startFolderPath, string endFolderPath)
{
    //在建立目標資料夾
    Directory.CreateDirectory(endFolderPath);
    DirectoryInfo startDir = new DirectoryInfo(startFolderPath);
    //迴圈複製資料夾下的所有檔案
    foreach (FileInfo item in startDir.GetFiles())
    {
        File.Copy(item.FullName, endFolderPath + "\\" + item.Name);
    }
    //迴圈所有子資料夾形成遞迴呼叫
    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;
    }
}
//複製資料夾
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;
    //判斷目標地址是否已經有該檔案夾了
    if (Directory.Exists(newFolderName))
    {
        //方案一:給出提示
        //MessageBox.Show("在目標位置,該資料夾已經存在了");
        //return;

        //方案二:刪除目標位置的資料夾
        Directory.Delete(newFolderName, true);
    }
    CopyFolder(this.txtFolder1.Text, newFolderName);
    MessageBox.Show("複製成功!");
}

//移動資料夾
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;
    //判斷目標地址是否已經有該檔案夾了
    if (Directory.Exists(newFolderName))
    {
        //方案一:給出提示
        //MessageBox.Show("在目標位置,該資料夾已經存在了");
        //return;

        //方案二:刪除目標位置的資料夾
        Directory.Delete(newFolderName, true);
    }
    CopyFolder(this.txtFolder1.Text, newFolderName);
    //複製完成後,刪除原始位置的資料夾
    Directory.Delete(this.txtFolder1.Text, true);
    MessageBox.Show("移動成功!");
}

三、讀寫文字檔案

檔案和流的概念:

--檔案是在各種媒質上永久儲存的資料的有序集合。它是進行資料讀寫操作的基本物件。

--流是一種向儲存器讀取和寫入位元組的方式,也是進行資料讀寫操作的基本物件。

--流提供了連續的位元組流儲存空間,其實際儲存位置可以不連續。

--C#中所有表示流的類都繼承於抽象類Stream。

讀寫文字檔案最常用的類有:

--FileStream(檔案流)

--StreamReader(流讀取器)

--StreamWriter(流寫入器)

讀寫檔案操作的基本步驟為:

  1. 建立檔案流
  2. 建立讀、寫器
  3. 執行讀、寫操作
  4. 關閉讀寫器
  5. 關閉檔案流

檔案流物件:

例項化檔案流物件語法如下:

FileStream fs = new FileStream(FileName, FileMode,FileAccess);

其中FileMode的列舉值如下:

值名稱 功能說明
CreateNew 建立新檔案,如果檔案已存在則引發異常
Create 建立新檔案,如果檔案已存在則覆蓋
Open 開啟檔案,如果檔案不存在則引發異常
OpenOrCreate 開啟檔案,如果檔案不存在則建立新檔案
Append 開啟檔案並查詢到檔案尾,如果檔案不存在則建立新檔案
Truncate 開啟現在檔案並清除其內容,如果檔案不存在則引發異常

其中FileAccess的列舉值如下:

值名稱 功能說明
Read 對檔案進行只讀訪問
Write 對檔案進行只寫訪問
ReadWrite 對檔案進行讀寫訪問

檔案讀寫器常用方法:

StreamReader的常用方法:

值名稱 功能說明
Read 讀取輸入流中的下一個(組)字元
ReadLine 讀取當前流中的一行字元,並將資料作為字串返回
ReadToEnd 讀取從當前位置到末尾的所有字元,並將資料作為字串返回
Close 關閉StreamReader物件和基礎流,並釋放與讀取器關聯的所有系統資源

StreamWriter的常用方法:

值名稱 功能說明
Write 將資料寫入流
WriteLine 將行結束符之前的資料寫入流
Close 關閉StreamWriter物件和基礎流

示例:如下圖,編寫一個文字檔案讀寫器

--點選"開啟檔案"按鈕,選擇一個文字檔案,並且將文字檔案路徑顯示在上面單行文字框中,將文字檔案的內容顯示在下面的多行文字框中。

--多行文字框,可以進行修改其文字內容。

--點選"儲存檔案"按鈕,將多行文字框的文字儲存到開啟的文字檔案中。

其中"開啟檔案"按鈕name=btOpen,"儲存檔案"按鈕name=btSave,單行文字框name=txtFilePath,多行文字框name=txtContent。

實現程式碼如下:

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將文字一次性全部轉換為位元組陣列,之後轉換為string
    //FileStream fs = new FileStream(this.txtFilePath.Text, FileMode.Open, FileAccess.Read);
    ////fs.Seek(0, SeekOrigin.Begin); //定位流,從開始位置移動0個位元組,也就是流的最開始位置
    //int len = (int)fs.Length; //獲取檔案的位元組長度 
    //byte[] arrByte = new byte[len]; //定義位元組陣列
    //fs.Read(arrByte, 0, arrByte.Length); //將檔案流讀入位元組陣列
    //this.txtContent.Text = Encoding.Default.GetString(arrByte,0,len);
    //fs.Close();

    //方案二:使用Filestream,逐位元組讀取文字,後將位元組轉換為string
    //FileStream fs = new FileStream(this.txtFilePath.Text, FileMode.Open, FileAccess.Read);
    //int len = (int)fs.Length; //獲取檔案的位元組長度 
    //byte[] arrByte = new byte[len]; //定義位元組陣列
    //int index = 0; //儲存位元組陣列變化的下標
    //int code = fs.ReadByte(); //讀取一個位元組
    //while (code != -1) //讀取內容等於-1即表示讀取完畢
    //{
    //    //將讀取內容轉換成位元組存入陣列
    //    arrByte[index] = Convert.ToByte(code); 
    //    code = fs.ReadByte();  //繼續逐位元組讀取
    //    index++;
    //}
    //this.txtContent.Text = Encoding.Default.GetString(arrByte, 0, len);
    //fs.Close();

	//方案三:直接使用File的Read All Text 函式將文字檔案內容全部讀入text
	//File.ReadAllBytes可以讀取成位元組陣列
	//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類靜態方法
    //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("儲存成功!");
}

四、序列化與反序列化

序列化就是將物件例項的狀態儲存到儲存媒介的過程。

序列化和反序列化的實現步驟(二進位制序列化):

(1)引入System.Runtime.Serialization.Formatters.Binary名稱空間

(2)要序列化的物件需要標記Serializable特性

(3)其父類和屬性中的引用型別也標記Serializable特性

(4)使用BinaryFormatter 物件的Serialize()方法和Deserialize()方法

(1)序列化單個物件

示例:如下圖,實現單個物件的序列化與反序列化

--輸入學生資訊,點選"儲存資訊"按鈕,將學生資訊永久序列化儲存到電腦上。

--關閉程式後,在啟動程式,可以將本地序列化檔案讀取,將資訊顯示在介面的文字框中。

其中,學號,姓名,年齡文字框的name分別為txtNo,txtName,txtAge。

儲存資訊和讀取資訊按鈕name分別為btSave和btRead。

具體實現程式碼如下:

定義一個學生類:

[Serializable]
class Student
{
    public string StuNo { get; set; } //學號
    public string StuName { get; set; } //姓名
    public int StuAge { get; set; } //年齡
}

其中[Serializable]關鍵字代表此類是可以被序列化的。

編寫按鈕響應事件程式碼:

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)序列化集合

示例:如下圖,實現集合的序列化

--開啟窗體,自動從序列化檔案中讀取資訊,並在listView列表上進行展示。

--輸入學生資訊,點選"新增資訊"按鈕,新增學生,並且序列化學生列表,重新整理ListView列表資料。

其中展示列表的ListView控制元件的name=listView1。

學號,姓名,年齡文字框的name分別為txtNo,txtName,txtAge。

新增資訊按鈕name=btSave。

具體實現程式碼如下:

定義一個學生類:

[Serializable]
class Student
{
    public string StuNo { get; set; } //學號
    public string StuName { get; set; } //姓名
    public int StuAge { get; set; } //年齡
}

其中[Serializable]關鍵字代表此類是可以被序列化的。

編寫按鈕響應事件程式碼:

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集合資料繫結到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();
}

本文來自部落格園,作者:農碼一生,轉載請註明原文連結:https://www.cnblogs.com/wml-it/p/15966457.html


技術的發展日新月異,隨著時間推移,無法保證本部落格所有內容的正確性。如有誤導,請大家見諒,歡迎評論區指正!
個人開原始碼連結,歡迎點亮:
GitHub:https://github.com/ITMingliang
Gitee:https://gitee.com/mingliang_it
GitLab:https://gitlab.com/ITMingliang
進開發學習交流群: