C# TextReader
最后修改于 2025 年 4 月 20 日
本教程讲解如何在 C# 中使用 TextReader 类从各种来源读取文本数据。TextReader 是一个抽象类,它提供了读取字符流的方法。
TextReader 类是 StreamReader 和 StringReader 的基类。 它提供了一个方便的 API,用于从不同的输入源读取文本数据。
TextReader
旨在读取字符输入,而不是二进制数据。 当与它的具体实现一起使用时,它会自动处理文本编码。
基本 TextReader 示例
此示例演示如何使用从 TextReader 继承的 StreamReader 从文件中读取文本。 我们逐行读取文本文件。
using System; using System.IO; class Program { static void Main() { // Create a sample text file first File.WriteAllText("example.txt", "First line\nSecond line\nThird line"); // Read using TextReader (StreamReader) using (TextReader reader = new StreamReader("example.txt")) { string line; while ((line = reader.ReadLine()) != null) { Console.WriteLine(line); } } } }
该示例创建一个包含三行的文本文件,然后使用 StreamReader 将其读回。 当到达文件末尾时,ReadLine
方法返回 null。 这种模式通常用于逐行处理文本文件。
using
语句确保正确清理资源。 StreamReader 会根据文件的字节顺序标记 (BOM) 自动处理文件编码检测(如果存在)。
读取整个文件内容
TextReader 提供了立即读取整个内容的方法。 此示例显示如何将整个文件读入字符串。
using System; using System.IO; class Program { static void Main() { // Create a sample text file File.WriteAllText("document.txt", "This is the complete content\nof our text file."); // Read entire content using (TextReader reader = new StreamReader("document.txt")) { string content = reader.ReadToEnd(); Console.WriteLine("File content:"); Console.WriteLine(content); } } }
ReadToEnd
方法读取从当前位置到文本流末尾的所有字符。 这对于内存使用量不是问题的小文件很有用。
对于大文件,请考虑逐行或分块读取,以避免高内存消耗。 该示例显示了在适当情况下读取完整文件内容的简单性。
单独读取字符
TextReader 允许读取单个字符或字符块。 此示例演示了逐字符读取。
using System; using System.IO; class Program { static void Main() { File.WriteAllText("chars.txt", "ABC"); using (TextReader reader = new StreamReader("chars.txt")) { int charCode; while ((charCode = reader.Read()) != -1) { char c = (char)charCode; Console.WriteLine($"Read character: {c} ({(int)c})"); } } } }
Read
方法将下一个字符作为整数返回,或者在流结尾返回 -1。 我们将整数转换为 char 以进行显示。 这种低级别的方法提供了对文本处理的精确控制。
逐字符读取对于解析任务或处理具有特定格式要求的文本非常有用。 该示例同时显示了字符及其 Unicode 代码点。
读取字符块
为了更好地处理大文件,TextReader 可以读取字符块。 此示例一次读取 10 个字符的块。
using System; using System.IO; class Program { static void Main() { File.WriteAllText("lorem.txt", "Lorem ipsum dolor sit amet, consectetur adipiscing elit."); using (TextReader reader = new StreamReader("lorem.txt")) { char[] buffer = new char[10]; int charsRead; while ((charsRead = reader.ReadBlock(buffer, 0, buffer.Length)) > 0) { string chunk = new string(buffer, 0, charsRead); Console.WriteLine($"Read {charsRead} chars: {chunk}"); } } } }
ReadBlock
读取最多指定数量的字符,并返回实际读取的计数。 该缓冲区被重用于每个读取操作。 这种方法对于大型文件来说是节省内存的。
该示例显示了如何每次处理读取的准确字符数。 可以根据性能要求和典型文件大小调整缓冲区大小。
使用 StringReader
StringReader 是另一个 TextReader 实现,它从字符串读取。 此示例演示了从内存中字符串读取。
using System; using System.IO; class Program { static void Main() { string text = "Line 1\nLine 2\nLine 3"; using (TextReader reader = new StringReader(text)) { string line; int lineNumber = 1; while ((line = reader.ReadLine()) != null) { Console.WriteLine($"Line {lineNumber}: {line}"); lineNumber++; } } } }
StringReader 提供了与 StreamReader 相同的接口,但处理的是字符串而不是文件。 这对于测试或处理内存中的文本数据很有用。
该示例显示了当文本源更改时,StringReader 如何与 StreamReader 互换使用。 相同的读取模式适用于这两种实现。
查看下一个字符
TextReader 的 Peek
方法允许查看下一个字符而不使用它。 此示例演示了查看。
using System; using System.IO; class Program { static void Main() { File.WriteAllText("peek.txt", "ABC"); using (TextReader reader = new StreamReader("peek.txt")) { // Peek at first character int firstChar = reader.Peek(); Console.WriteLine($"First character will be: {(char)firstChar}"); // Now read it int readChar = reader.Read(); Console.WriteLine($"Actually read: {(char)readChar}"); // Verify they match Console.WriteLine($"Peeked and read match: {firstChar == readChar}"); } } }
Peek
返回下一个字符而不推进位置。 它在流结尾返回 -1,就像 Read
一样。 这对于前瞻性解析很有用。
该示例显示了查看如何允许在决定如何处理下一个字符之前检查它。 查看的字符仍然可用于后续读取操作。
将 TextReader 与其他 API 结合使用
TextReader 与其他 .NET API 集成良好。 此示例将 TextReader 与 LINQ 结合使用来处理行。
using System; using System.IO; using System.Linq; class Program { static void Main() { File.WriteAllText("data.txt", "10\n20\n30\n40\n50"); using (TextReader reader = new StreamReader("data.txt")) { var numbers = reader.ReadToEnd() .Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries) .Select(int.Parse) .Where(n => n > 25) .OrderByDescending(n => n); Console.WriteLine("Numbers > 25:"); foreach (var num in numbers) { Console.WriteLine(num); } } } }
该示例读取所有内容,分割成行,转换为整数,过滤和排序。 这显示了 TextReader 与 LINQ 操作的兼容性,可实现强大的文本处理。
对于非常大的文件,请考虑在带有 LINQ 惰性求值的循环中使用 ReadLine
,而不是 ReadToEnd
。 该方法取决于文件大小和处理需求。
来源
本教程介绍了在 C# 中使用 TextReader 读取文本数据,包括逐行读取、完整内容读取和字符处理。 我们探讨了 StreamReader 和 StringReader 实现。
作者
列出所有 C# 教程。