C# StreamReader
最后修改于 2025 年 4 月 20 日
本教程介绍了如何在 C# 中使用 StreamReader 类从文件中读取文本数据。 StreamReader 提供了从具有各种编码的流中读取字符数据的方法。
StreamReader 类以特定的编码从字节流中读取字符。 它继承自 TextReader,专为高效读取文本文件而设计。
StreamReader 自动处理不同的文本编码,如 UTF-8、Unicode 和 ASCII。 它提供了读取行、整个文件或逐字符处理的方法。
StreamReader 基础示例
此示例演示了如何使用 StreamReader 逐行读取文本文件。 它展示了处理文本文件的最简单方法。
using System;
using System.IO;
class Program
{
static void Main()
{
string filePath = "example.txt";
// Create a sample file first
File.WriteAllText(filePath, "First line\nSecond line\nThird line");
// Read the file line by line
using (StreamReader reader = new StreamReader(filePath))
{
string line;
int lineNumber = 1;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine($"Line {lineNumber}: {line}");
lineNumber++;
}
}
}
}
该程序首先创建一个包含三行的示例文本文件。 然后它使用 StreamReader 逐行读取文件。 当到达文件末尾时,ReadLine 方法返回 null。
using 语句确保正确清理资源。 每行都打印其行号。 这种模式在 C# 中很常见于文本文件处理。
一次性读取整个文件
StreamReader 可以使用 ReadToEnd 一次性读取整个文件。 这对于可以放入内存的小文件很有用。
using System;
using System.IO;
class Program
{
static void Main()
{
string filePath = "document.txt";
// Create sample file
File.WriteAllText(filePath, "This is the entire content\nof the text file.");
// Read entire file
using (StreamReader reader = new StreamReader(filePath))
{
string content = reader.ReadToEnd();
Console.WriteLine("File content:");
Console.WriteLine(content);
Console.WriteLine($"\nTotal characters: {content.Length}");
}
}
}
ReadToEnd 读取从当前位置到流结尾的所有字符。 它返回一个包含整个文件内容的字符串。
这种方法很简单,但应谨慎用于大型文件。 对于大文件,逐行读取更节省内存。
逐字符读取
StreamReader 提供了 Read 方法来读取单个字符。 此示例显示了如何逐字符处理文件。
using System;
using System.IO;
class Program
{
static void Main()
{
string filePath = "chars.txt";
File.WriteAllText(filePath, "ABC\n123");
using (StreamReader reader = new StreamReader(filePath))
{
int ch;
int count = 0;
while ((ch = reader.Read()) != -1)
{
count++;
Console.WriteLine($"Char {count}: {(char)ch} (Unicode: {ch})");
}
Console.WriteLine($"\nTotal characters read: {count}");
}
}
}
Read 方法返回下一个字符作为整数,或者在文件末尾返回 -1。 我们将整数转换为 char 以进行显示。
这种方法对于需要单独检查每个字符的底层文本处理非常有用。 请注意,它包括换行符。
指定文件编码
StreamReader 可以处理不同的文本编码。 此示例演示了如何读取具有特定编码(如 UTF-8 和 Unicode)的文件。
using System;
using System.IO;
using System.Text;
class Program
{
static void Main()
{
string filePath = "unicode.txt";
// Create file with Unicode encoding
File.WriteAllText(filePath, "Привет мир!", Encoding.Unicode);
// Read with explicit encoding
using (StreamReader reader = new StreamReader(filePath, Encoding.Unicode))
{
string content = reader.ReadToEnd();
Console.WriteLine("Read content: " + content);
Console.WriteLine("\nFirst character: " + content[0]);
Console.WriteLine("Encoding: " + reader.CurrentEncoding.EncodingName);
}
}
}
该示例使用 Unicode 编码写入文本,并使用相同的编码将其读回。 CurrentEncoding 显示正在使用的编码。
读取非 ASCII 文本文件时,始终指定正确的编码。 默认编码是 UTF-8,但许多旧系统使用其他编码。
查看下一个字符
StreamReader 的 Peek 方法允许查看下一个字符而不消耗它。 这对于解析场景非常有用。
using System;
using System.IO;
class Program
{
static void Main()
{
string filePath = "data.txt";
File.WriteAllText(filePath, "ABC\n123");
using (StreamReader reader = new StreamReader(filePath))
{
Console.WriteLine("Peek first: " + (char)reader.Peek());
Console.WriteLine("Read first: " + (char)reader.Read());
Console.WriteLine("Peek again: " + (char)reader.Peek());
Console.WriteLine("Read again: " + (char)reader.Read());
}
}
}
Peek 返回下一个字符而不推进位置。 它在文件末尾返回 -1,就像 Read 一样。
当您需要在流中向前看以决定如何处理下一个字符时,此方法特别有用,例如在解析器中。
使用缓冲区读取
对于性能关键型应用程序,StreamReader 可以将字符块读入缓冲区。 此示例显示了基于缓冲区的读取。
using System;
using System.IO;
using System.Text;
class Program
{
static void Main()
{
string filePath = "largefile.txt";
// Create a large sample file
var sb = new StringBuilder();
for (int i = 0; i < 1000; i++)
{
sb.AppendLine($"Line {i + 1}");
}
File.WriteAllText(filePath, sb.ToString());
// Read with buffer
char[] buffer = new char[128];
using (StreamReader reader = new StreamReader(filePath))
{
int charsRead;
int totalChars = 0;
while ((charsRead = reader.Read(buffer, 0, buffer.Length)) > 0)
{
totalChars += charsRead;
Console.Write($"Read {charsRead} chars: ");
Console.WriteLine(new string(buffer, 0, Math.Min(20, charsRead)) + "...");
}
Console.WriteLine($"\nTotal characters read: {totalChars}");
}
}
}
Read 重载使用来自流的数据填充字符缓冲区。 它返回实际读取的字符数。
对于大型文件,缓冲读取比逐字符处理更有效。 可以调整缓冲区大小以获得最佳性能。
从 MemoryStream 读取
StreamReader 可以从任何 Stream 读取,包括 MemoryStream。 此示例显示了从内存中读取文本数据。
using System;
using System.IO;
using System.Text;
class Program
{
static void Main()
{
// Create text in memory
string text = "This text is in memory\nSecond line\nThird line";
byte[] bytes = Encoding.UTF8.GetBytes(text);
// Read from MemoryStream
using (var memoryStream = new MemoryStream(bytes))
using (var reader = new StreamReader(memoryStream))
{
Console.WriteLine("Reading from MemoryStream:");
string line;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine("> " + line);
}
}
}
}
该示例将字符串转换为字节,从这些字节创建 MemoryStream,然后使用 StreamReader 读取它。 这种模式对于处理从网络或其他来源接收的文本数据非常有用。
StreamReader 对 MemoryStream 的工作方式与对文件流的工作方式相同,展示了它在不同流源中的灵活性。
来源
本教程介绍了在 C# 中使用 StreamReader 读取文本数据,包括逐行读取、编码、缓冲和内存流。 StreamReader 可用于所有文本处理需求。
作者
列出所有 C# 教程。