在 .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 componentstextBox = new TextBox { Multiline = true, Dock = DockStyle.Fill, ScrollBars = ScrollBars.Both };menuStrip = new MenuStrip();openMenuItem = new ToolStripMenuItem("Open");saveMenuItem = new ToolStripMenuItem("Save");// Set up menumenuStrip.Items.Add(openMenuItem);menuStrip.Items.Add(saveMenuItem);this.Controls.Add(menuStrip);this.Controls.Add(textBox);this.MainMenuStrip = menuStrip;// Event handlersopenMenuItem.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());}
}