C#讀寫文本文件的多種方式詳解
在 C# 編程中,文件讀寫是一項(xiàng)非?;A(chǔ)且重要的操作。無(wú)論是保存用戶數(shù)據(jù)、讀取配置文件還是處理日志信息,都離不開文件操作。本文將詳細(xì)介紹 C# 中各種常用的文件讀寫方式,包括文本文件、二進(jìn)制文件、CSV 文件、JSON 文件等,并提供相應(yīng)的代碼示例,幫助你根據(jù)實(shí)際需求選擇合適的方法。
一、文本文件讀寫
文本文件是最常見的文件類型,C# 提供了多種方式來(lái)讀寫文本文件。
1. 使用 File 類的靜態(tài)方法
File 類提供了一系列靜態(tài)方法,可以方便地進(jìn)行文本文件的讀寫操作,適合處理小型文本文件。
using System; using System.IO; class Program { static void Main() { // 寫入文本文件 string content = "Hello, World!"; string path = "test.txt"; // 寫入所有文本 File.WriteAllText(path, content); Console.WriteLine("文件寫入成功"); // 讀取所有文本 string readContent = File.ReadAllText(path); Console.WriteLine("讀取的內(nèi)容:" + readContent); // 寫入多行文本 string[] lines = { "第一行", "第二行", "第三行" }; File.WriteAllLines(path, lines); Console.WriteLine("多行文本寫入成功"); // 讀取所有行 string[] readLines = File.ReadAllLines(path); Console.WriteLine("讀取的多行內(nèi)容:"); foreach (string line in readLines) { Console.WriteLine(line); } } }
優(yōu)點(diǎn):代碼簡(jiǎn)潔,一行代碼即可完成讀寫操作。
缺點(diǎn):會(huì)將整個(gè)文件內(nèi)容加載到內(nèi)存中,不適合處理大型文件。
2. 使用 StreamReader 和 StreamWriter
StreamReader 和 StreamWriter 適合處理大型文本文件,可以逐行讀寫,節(jié)省內(nèi)存。
using System; using System.IO; class Program { static void Main() { string path = "largefile.txt"; // 使用StreamWriter寫入 using (StreamWriter sw = new StreamWriter(path)) { sw.WriteLine("第一行內(nèi)容"); sw.WriteLine("第二行內(nèi)容"); sw.Write("這是第三行的"); sw.Write("一部分內(nèi)容"); } // 使用StreamReader讀取 using (StreamReader sr = new StreamReader(path)) { string line; Console.WriteLine("文件內(nèi)容:"); while ((line = sr.ReadLine()) != null) { Console.WriteLine(line); } } // 讀取全部?jī)?nèi)容 using (StreamReader sr = new StreamReader(path)) { string allContent = sr.ReadToEnd(); Console.WriteLine("n全部?jī)?nèi)容:"); Console.WriteLine(allContent); } } }
優(yōu)點(diǎn):可以逐行處理,內(nèi)存占用小,適合大型文件。
缺點(diǎn):代碼相對(duì)復(fù)雜一些。
注意:使用using
語(yǔ)句可以確保流正確關(guān)閉和釋放資源。
二、二進(jìn)制文件讀寫
二進(jìn)制文件適用于存儲(chǔ)圖像、音頻、視頻等非文本數(shù)據(jù),或者需要緊湊存儲(chǔ)的結(jié)構(gòu)化數(shù)據(jù)。
1. 使用 FileStream 類
FileStream 是一個(gè)通用的字節(jié)流類,可以用于讀寫任何類型的文件。
using System; using System.IO; class Program { static void Main() { string path = "data.bin"; // 寫入二進(jìn)制數(shù)據(jù) byte[] data = { 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64 }; // "Hello World"的ASCII碼 using (FileStream fs = new FileStream(path, FileMode.Create)) { fs.Write(data, 0, data.Length); } // 讀取二進(jìn)制數(shù)據(jù) using (FileStream fs = new FileStream(path, FileMode.Open)) { byte[] readData = new byte[fs.Length]; fs.Read(readData, 0, readData.Length); Console.WriteLine("讀取的二進(jìn)制數(shù)據(jù)轉(zhuǎn)換為字符串:"); Console.WriteLine(System.Text.Encoding.ASCII.GetString(readData)); Console.WriteLine("十六進(jìn)制表示:"); foreach (byte b in readData) { Console.Write($"{b:X2} "); } } } }
2. 使用 BinaryReader 和 BinaryWriter
BinaryReader 和 BinaryWriter 提供了更方便的方法來(lái)讀寫基本數(shù)據(jù)類型。
using System; using System.IO; class Program { static void Main() { string path = "binarydata.bin"; // 寫入各種數(shù)據(jù)類型 using (BinaryWriter bw = new BinaryWriter(File.Open(path, FileMode.Create))) { bw.Write(123); // int bw.Write(3.14159); // double bw.Write(true); // bool bw.Write("Hello World"); // string bw.Write(new char[] { 'a', 'b', 'c' }); // char數(shù)組 } // 讀取各種數(shù)據(jù)類型 using (BinaryReader br = new BinaryReader(File.Open(path, FileMode.Open))) { Console.WriteLine("int值: " + br.ReadInt32()); Console.WriteLine("double值: " + br.ReadDouble()); Console.WriteLine("bool值: " + br.ReadBoolean()); Console.WriteLine("string值: " + br.ReadString()); char[] chars = br.ReadChars(3); Console.WriteLine("char數(shù)組: " + new string(chars)); } } }
注意:使用 BinaryReader 和 BinaryWriter 時(shí),讀取順序必須與寫入順序一致。
三、使用 FileStream 進(jìn)行高級(jí)操作
FileStream 提供了更多控制選項(xiàng),適合需要精細(xì)控制文件操作的場(chǎng)景。
using System; using System.IO; class Program { static void Main() { string sourcePath = "source.txt"; string destPath = "destination.txt"; // 創(chuàng)建源文件 File.WriteAllText(sourcePath, "這是一個(gè)用于演示文件流操作的示例文本。"); // 使用FileStream復(fù)制文件 using (FileStream sourceStream = new FileStream(sourcePath, FileMode.Open, FileAccess.Read)) using (FileStream destStream = new FileStream(destPath, FileMode.Create, FileAccess.Write)) { byte[] buffer = new byte[1024]; int bytesRead; Console.WriteLine("開始復(fù)制文件..."); // 每次讀取1024字節(jié)并寫入 while ((bytesRead = sourceStream.Read(buffer, 0, buffer.Length)) > 0) { destStream.Write(buffer, 0, bytesRead); Console.WriteLine($"已復(fù)制 {bytesRead} 字節(jié)"); } Console.WriteLine("文件復(fù)制完成"); } // 驗(yàn)證復(fù)制結(jié)果 if (File.ReadAllText(sourcePath) == File.ReadAllText(destPath)) { Console.WriteLine("復(fù)制的文件內(nèi)容與源文件一致"); } } }
FileMode 枚舉:控制打開或創(chuàng)建文件的方式,常見值有 Create、Open、Append 等。
FileAccess 枚舉:指定對(duì)文件的訪問(wèn)權(quán)限,有 Read、Write、ReadWrite。
緩沖操作:使用緩沖區(qū)可以提高大文件操作的效率。
四、特定格式文件讀寫
1. CSV 文件讀寫
CSV(逗號(hào)分隔值)文件是一種常見的表格數(shù)據(jù)格式。
using System; using System.Collections.Generic; using System.IO; class Program { static void Main() { string path = "data.csv"; // 寫入CSV文件 var data = new List<string[]> { new[] { "姓名", "年齡", "城市" }, new[] { "張三", "25", "北京" }, new[] { "李四", "30", "上海" }, new[] { "王五", "35", "廣州" } }; using (StreamWriter sw = new StreamWriter(path)) { foreach (var row in data) { sw.WriteLine(string.Join(",", row)); } } // 讀取CSV文件 using (StreamReader sr = new StreamReader(path)) { string line; while ((line = sr.ReadLine()) != null) { string[] columns = line.Split(','); Console.WriteLine(string.Join(" | ", columns)); } } } }
注意:以上是簡(jiǎn)單實(shí)現(xiàn),實(shí)際應(yīng)用中可能需要處理包含逗號(hào)的字段(通常用引號(hào)括起來(lái)),這時(shí)可以考慮使用專門的 CSV 庫(kù)如 CsvHelper。
2. JSON 文件讀寫
JSON 是一種輕量級(jí)的數(shù)據(jù)交換格式,在現(xiàn)代應(yīng)用中廣泛使用。
需要先安裝 Newtonsoft.Json 包(NuGet 命令:Install-Package Newtonsoft.Json)
using System; using System.Collections.Generic; using Newtonsoft.Json; // 定義一個(gè)示例類 public class Person { public string Name { get; set; } public int Age { get; set; } public string City { get; set; } } class Program { static void Main() { string path = "people.json"; // 創(chuàng)建示例數(shù)據(jù) var people = new List<Person> { new Person { Name = "張三", Age = 25, City = "北京" }, new Person { Name = "李四", Age = 30, City = "上海" }, new Person { Name = "王五", Age = 35, City = "廣州" } }; // 寫入JSON文件 string json = JsonConvert.SerializeObject(people, Formatting.Indented); File.WriteAllText(path, json); // 讀取JSON文件 string jsonFromFile = File.ReadAllText(path); List<Person> peopleFromFile = JsonConvert.DeserializeObject<List<Person>>(jsonFromFile); // 顯示讀取結(jié)果 foreach (var person in peopleFromFile) { Console.WriteLine($"姓名: {person.Name}, 年齡: {person.Age}, 城市: {person.City}"); } } }
在.NET Core 3.0 及以上版本,也可以使用內(nèi)置的 System.Text.Json:
// 寫入JSON文件 string json = System.Text.Json.JsonSerializer.Serialize(people, new System.Text.Json.JsonSerializerOptions { WriteIndented = true }); File.WriteAllText(path, json); // 讀取JSON文件 string jsonFromFile = File.ReadAllText(path); List<Person> peopleFromFile = System.Text.Json.JsonSerializer.Deserialize<List<Person>>(jsonFromFile);
五、文件操作的注意事項(xiàng)
1. 異常處理
文件操作可能會(huì)拋出各種異常,如文件不存在、權(quán)限不足等,需要進(jìn)行適當(dāng)?shù)漠惓L幚怼?/p>
try { string content = File.ReadAllText("test.txt"); Console.WriteLine(content); } catch (FileNotFoundException) { Console.WriteLine("文件不存在"); } catch (UnauthorizedAccessException) { Console.WriteLine("沒(méi)有訪問(wèn)權(quán)限"); } catch (IOException ex) { Console.WriteLine($"IO錯(cuò)誤: {ex.Message}"); } catch (Exception ex) { Console.WriteLine($"發(fā)生錯(cuò)誤: {ex.Message}"); }
2. 路徑處理
使用 Path 類來(lái)處理文件路徑,避免跨平臺(tái)問(wèn)題。
// 組合路徑 string directory = "data"; string fileName = "info.txt"; string fullPath = Path.Combine(directory, fileName); Console.WriteLine("完整路徑: " + fullPath); // 獲取文件名 Console.WriteLine("文件名: " + Path.GetFileName(fullPath)); // 獲取文件擴(kuò)展名 Console.WriteLine("擴(kuò)展名: " + Path.GetExtension(fullPath)); // 獲取目錄名 Console.WriteLine("目錄名: " + Path.GetDirectoryName(fullPath));
3. 異步操作
對(duì)于 UI 應(yīng)用程序,使用異步文件操作可以避免界面卡頓。
using System; using System.IO; using System.Threading.Tasks; class Program { static async Task Main() { string path = "async_test.txt"; // 異步寫入 string content = "這是一個(gè)異步寫入的示例"; await File.WriteAllTextAsync(path, content); Console.WriteLine("異步寫入完成"); // 異步讀取 string readContent = await File.ReadAllTextAsync(path); Console.WriteLine("異步讀取內(nèi)容: " + readContent); // 異步流操作 using (StreamWriter sw = new StreamWriter(path, append: true)) { await sw.WriteLineAsync("這是追加的一行"); } using (StreamReader sr = new StreamReader(path)) { string line; Console.WriteLine("文件內(nèi)容:"); while ((line = await sr.ReadLineAsync()) != null) { Console.WriteLine(line); } } } }
六、總結(jié)
C# 提供了豐富的文件操作方式,選擇合適的方法取決于具體需求:
- 對(duì)于小型文本文件,F(xiàn)ile 類的靜態(tài)方法最簡(jiǎn)單方便
- 對(duì)于大型文本文件,StreamReader 和 StreamWriter 更合適
- 對(duì)于二進(jìn)制文件,使用 FileStream、BinaryReader 和 BinaryWriter
- 對(duì)于 CSV 和 JSON 等特定格式,可使用相應(yīng)的方法或庫(kù)
無(wú)論使用哪種方式,都應(yīng)該注意:
- 使用 using 語(yǔ)句確保資源正確釋放
- 進(jìn)行適當(dāng)?shù)漠惓L幚?/li>
- 注意路徑處理和跨平臺(tái)兼容性
- 對(duì)于 UI 應(yīng)用,優(yōu)先考慮異步操作
掌握這些文件操作技巧,將有助于你更好地處理各種數(shù)據(jù)存儲(chǔ)和讀取需求,提高應(yīng)用程序的靈活性和可靠性。
到此這篇關(guān)于C#讀寫文本文件的多種方式詳解的文章就介紹到這了,更多相關(guān)C#讀寫文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于WPF實(shí)現(xiàn)3D導(dǎo)航欄控件
這篇文章主要介紹了如何基于WPF實(shí)現(xiàn)簡(jiǎn)單的3D導(dǎo)航欄控件效果,文中的示例代碼講解詳細(xì),對(duì)我們的學(xué)習(xí)或工作有一定幫助,需要的小伙伴可以參考一下2024-03-03詳解c#中Array,ArrayList與List<T>的區(qū)別、共性與相互轉(zhuǎn)換
本文詳細(xì)講解了c#中Array,ArrayList與List<T>的區(qū)別、共性與相互轉(zhuǎn)換,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-12-12C#實(shí)現(xiàn)PDF合并的項(xiàng)目實(shí)踐
有時(shí)我們可能會(huì)遇到需要的資料或教程被分成了幾部分存放在多個(gè)PDF文件中,本文主要介紹了C#實(shí)現(xiàn)PDF合并的項(xiàng)目實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01C#實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08c#菜單動(dòng)態(tài)合并的實(shí)現(xiàn)方法
這篇文章主要介紹了c#菜單動(dòng)態(tài)合并的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10