先看看 StreamReader,将前面的示例转换为读取文件以使用 StreamReader。它现在看起来容易得多。StreamReader 的构造函数接收FileStream。使用 EndOfStream 属性可以检查文件的末尾,使用ReadLine 方法读取文本行:
public static void ReadFileUsingReader(string fileName)
{var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);using (var reader = new StreamReader(stream)){while (!reader.EndofStream){string line = reader.ReadLine(); Console.WriteLine(line);}}
}
不再需要处理字节数组和编码。然而注意,StreamReader 默认使用 UTF-8 编码。指定另一个构造函数,可以让 StreamReader 使用文件中序言定义的编码:
var reader = new StreamReader(stream, detectEncodingFromByteOrderMarks: true);
也可以显式地指定编码:
var reader = new StreamReader(stream, Encoding.Unicode);
其他构造函数允许设置要使用的缓冲区;默认为 1024 个字节。此外,还可以指定关闭读取器时不应该关闭底层流。默认情况下,关闭读取器时(使用 Dispose 方法),会关闭底层流。
不显式实例化新的 StreamReader,而可以使用 File 类的 OpenText 方法创建StreamReader:
var reader = File.OpenText(fileName);
对于读取文件的代码片段,该文件使用 ReadLine 方法逐行读取。StreamReader还允许在流中使用 ReadToEnd 从光标的位置读取完整的文件:
string content = reader.ReadToEnd();
StreamReader 还允许把内容读入一个字符数组。这类似于 Stream 类的 Read 方法;它不读入字节数组,而是读入 char 数组。记住,char 类型使用两个字节。这适合于 16 位 Unicode,但不适合于 UTF-8,其中,一个字符的长度可以是 1 至 6 个字节:
int nChars = 100;
char[] charArray = new char[nChars];
int nCharsRead = reader.Read(charArray, 0, nChars);
StreamWriter 的工作方式与 StreamReader 相同,只是 StreamWriter 仅用于写入文件(或写入另一个流)。下面的代码片段传递 FileStream,创建了一个 StreamWriter。然后把传入的字符串数组写入流:
public static void WritefileUsingWriter(string fileName, string[] lines)
{var outputStream = File.OpenWrite(fileName); using (var writer = new StreamWriter(outputStream)) {byte[] preamble = Encoding.UTF8.GetPreamble();outputStream.Write(preamble, 0, preamble.Length); writer.Write(lines);}
}
记住,StreamWriter 默认使用 UTF-8 格式写入文本内容。通过在构造函数中设置 Encoding 对象,可以定义替代的内容。另外,类似于 StreamReader 的构造函数,StreamWriter 允许指定缓冲区的大小,以及关闭写入器时是否不应该关闭底层流。
StreamWriter 的 Write() 方法定义了 17 个重载版本,允许传递字符串和一些 .NET 数据类型。请记住,使用传递 .NET 数据类型的方法,这些都会使用指定的编码变成字符串。
微信公众号
Dotnet讲堂