WinForm RichTextBox 載入大量文字卡死和UTF-8亂碼問題

2023-07-28 12:01:28

在RichTextBox控制元件的使用中我們會遇到載入TXT檔案的問題,通常我們會有兩種處理方式。

一、載入TXT字串,設定到RichTextBox

//開啟並且讀取檔案資料
FileStream fs = new FileStream(txtPath, FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(fs, Encoding.UTF8);

//讀取到的所有文字字串
string str = sr.ReadToEnd();
//將讀取到的文字賦值到richTextBox中
richTextBox.Text = str;

sr.Close();
fs.Close();

這種方式不會存在編碼問題,只要你new StreamReader(fs, Encoding.UTF8)的編碼和檔案編碼一樣,讀取的string是正常的,然後再賦值到richTextBox.Text即可。

但是這種方式會使RichTextBox載入的時候非常卡。
所以我們還有另外一種方式,RichTextBox.LoadFile方法直接載入檔案進RichTextBox中。

二、RichTextBox.LoadFile()載入

如果直接用 public void LoadFile (string path); 需要檔案是RTF或者ASCII文字,顯然我們是要載入TXT並且我的檔案是UTF-8編碼。
所以我們使用LoadFile(Stream, RichTextBoxStreamType)直接載入檔案流,可能因為是流的關係,RichTextBox內部能緩衝載入或者其他原因,所以這種方式RichTextBox不會卡頓。

實現如下程式碼,讀取流並載入。

FileStream fs = new FileStream(txtPath, FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(fs, Encoding.UTF8);
//sr.BaseStream 獲取Stream基礎流
richTextBox.LoadFile(sr.BaseStream, RichTextBoxStreamType.PlainText);

fs.Close();
sr.Close();

關於RichTextBoxStreamType.PlainText引數:

我們使用PlainText載入純文字。

三、亂碼

當使用上面二的方式載入UTF-8編碼的TXT的時候內容全是亂碼。

排查後發現問題出在RichTextBoxStreamType.PlainText上,如果按這個方式載入,那麼讀取的編碼是按照預設編碼,也就是System.Text.Encoding.Default
當用System.Text.Encoding.Default 獲取編碼後發現預設編碼是GB2312,所以必然會出現亂碼。同時我們也不應該將其轉成GB231,因為有些UTF-8程式碼無法轉換到GB2312。
所以我們將檔案轉換成Unicode即可,並且RichTextBoxStreamType列舉值使用UnicodePlainText

FileStream fs = new FileStream(txtPath, FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(fs, Encoding.UTF8);
//utf-8轉Unicode
byte[] buffer = Encoding.Convert(Encoding.UTF8, Encoding.Unicode, Encoding.UTF8.GetBytes(sr.ReadToEnd()));
//將byte[]轉換位記憶體流
Stream stream = new MemoryStream(buffer);
//RichTextBoxStreamType.UnicodePlainText 載入
richTextBox.LoadFile(stream, RichTextBoxStreamType.UnicodePlainText);

fs.Close();
sr.Close();
stream.Close();