在 .NET 中,流是处理输入和输出的基础概念。流分为字符流、字节流和缓冲流,每种流有其特定的用途和特性。以下是对这些流的总结:
1. 字符流(Character Streams)
特点:
- 用于处理字符数据,自动处理字符编码。
- 适合读取和写入文本文件。
主要类:
StreamReader
:从字符流中读取字符数据。支持多种字符编码(如 UTF-8、UTF-16)。提供方法如Read()
,ReadLine()
,ReadToEnd()
。StreamWriter
:向字符流中写入字符数据。支持字符编码设置。提供方法如Write()
,WriteLine()
。
示例:
// 写入文本
using (StreamWriter writer = new StreamWriter("example.txt"))
{
writer.WriteLine("Hello, World!");
}
// 读取文本
using (StreamReader reader = new StreamReader("example.txt"))
{
string content = reader.ReadToEnd();
Console.WriteLine(content);
}
2. 字节流(Byte Streams)
特点:
- 用于处理原始字节数据。适合二进制文件(如图片、音频)。
- 不处理字符编码,需要手动转换字节到字符。
主要类:
FileStream
:提供对文件的字节流读写操作。支持随机访问。提供方法如Read()
,Write()
,Seek()
。MemoryStream
:在内存中操作字节流。适用于临时数据存储。提供方法如Read()
,Write()
,ToArray()
。
示例:
// 写入字节
using (FileStream fs = new FileStream("example.bin", FileMode.Create, FileAccess.Write))
{
byte[] data = Encoding.UTF8.GetBytes("Hello, Binary World!");
fs.Write(data, 0, data.Length);
}
// 读取字节
using (FileStream fs = new FileStream("example.bin", FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
string text = Encoding.UTF8.GetString(buffer);
Console.WriteLine(text);
}
3. 缓冲流(Buffered Streams)
特点:
- 包装其他流以提高性能,通过在内部维护缓冲区减少实际读写操作的次数。
- 适用于大数据量的读写操作。
主要类:
BufferedStream
:对字节流进行缓冲,减少对底层流的直接操作。提供方法如Read()
,Write()
,Flush()
。
示例:
// 使用 BufferedStream 写入字节
using (FileStream fs = new FileStream("example.bin", FileMode.Create, FileAccess.Write))
using (BufferedStream bs = new BufferedStream(fs))
{
byte[] data = Encoding.UTF8.GetBytes("Hello, Buffered World!");
bs.Write(data, 0, data.Length);
}
// 使用 BufferedStream 读取字节
using (FileStream fs = new FileStream("example.bin", FileMode.Open, FileAccess.Read))
using (BufferedStream bs = new BufferedStream(fs))
using (StreamReader reader = new StreamReader(bs, Encoding.UTF8))
{
string content = reader.ReadToEnd();
Console.WriteLine(content);
}
总结
- 字符流:适用于文本数据处理,自动处理编码转换。
- 字节流:适用于原始数据和二进制文件处理,需要手动处理编码转换。
- 缓冲流:用于提高大数据量读写操作的性能,通过在内存中维护缓冲区减少对底层流的直接操作。
每种流类型都有其特定的用途,选择合适的流可以显著提高程序的效率和可读性。
--------------
FileStream
:读取和写入字节数据, 适用于处理原始字节数据,如二进制文件。用于处理大文件和支持随机访问,支持异步操作。StreamReader
和StreamWriter
:专注于文本数据的读取和写入,处理字符编码。File
和FileInfo
:提供静态和实例方法执行文件操作,FileInfo
提供更多操作功能。MemoryStream
:在内存中操作数据,适合临时数据处理。BufferedStream
:通过缓冲提高 I/O 操作性能
---------------
FileStream
可以直接读取文本文件,但它以字节为单位处理数据,因此你需要额外的步骤来将字节转换为字符串。使用 FileStream
读取文本文件的一般步骤包括:
- 打开文件:创建一个
FileStream
实例以读取文件。 - 读取数据:从流中读取字节数据。
- 转换字符:将读取的字节数据转换为字符串。
下面是一个示例:
using (FileStream fs = new FileStream("example.txt", FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
string text = Encoding.UTF8.GetString(buffer);
Console.WriteLine(text);
}
在这个示例中,我们使用 Encoding.UTF8.GetString()
方法将字节数组转换为 UTF-8 编码的字符串。根据文件的实际编码方式,可能需要选择不同的编码。
using System;
using System.IO;
using System.Text;
using System.Windows.Forms;
public class TextEditor : Form
{
private TextBox textBox;
private MenuStrip menuStrip;
private ToolStripMenuItem openMenuItem;
private ToolStripMenuItem saveMenuItem;
public TextEditor()
{
// Initialize components
textBox = new TextBox { Multiline = true, Dock = DockStyle.Fill, ScrollBars = ScrollBars.Both };
menuStrip = new MenuStrip();
openMenuItem = new ToolStripMenuItem("Open");
saveMenuItem = new ToolStripMenuItem("Save");
// Set up menu
menuStrip.Items.Add(openMenuItem);
menuStrip.Items.Add(saveMenuItem);
this.Controls.Add(menuStrip);
this.Controls.Add(textBox);
this.MainMenuStrip = menuStrip;
// Event handlers
openMenuItem.Click += OpenMenuItem_Click;
saveMenuItem.Click += SaveMenuItem_Click;
}
private void OpenMenuItem_Click(object sender, EventArgs e)
{
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
openFileDialog.Filter = "Text Files|*.txt|All Files|*.*";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
string filePath = openFileDialog.FileName;
textBox.Text = File.ReadAllText(filePath, Encoding.UTF8);
}
}
}
private void SaveMenuItem_Click(object sender, EventArgs e)
{
using (SaveFileDialog saveFileDialog = new SaveFileDialog())
{
saveFileDialog.Filter = "Text Files|*.txt|All Files|*.*";
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
string filePath = saveFileDialog.FileName;
File.WriteAllText(filePath, textBox.Text, Encoding.UTF8);
}
}
}
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new TextEditor());
}
}