20FileStream读写文件和(StreamReader、StreamWriter)
FileStream
用于操作字节(所有的文件本质都是字节形式存放的),也就是可以操作任意类型的文件
这个文件流可以用于操作大文件,对内存压力小
StreamReader和StreamWriter:用于操作字符(字符串),方便用于操作文本文件,和FileStream一样,都是用于操作大文件,这个针对文本文件的读写。
FileStream和File类的区别
FileStream和File的区别:有两个水缸,一个空的,一个满水,要把满水的给全部倒入空的里,
File是把水缸扛起来,一次性把所有的水(文件)倒入另一个水缸,(对内存不友好,因为他是把文件一次性读到内存里面)
FileStream则是用勺子,一勺一勺的盛在另一个水缸(对内存友好)
FileStream读取文件
这里先用来读写文本文件举例子
//第一步,创建FileStream的对象
//FileStream实例化时必须要给构造函数传参数,,一般使用三个参数
//第一个参数:一般是文件的路径
//第二个参数,表示针对这个文件做的操作
//第三个参数,表示你对这个文件里面的数据要进行的操作
FileStream fileStreamRead = new FileStream(@"C:\Users\Admin\Desktop\Test\new.txt", FileMode.OpenOrCreate, FileAccess.Read);
//第二步,创建字节数组,用于存放读到的文件,用该数组的长度限定每次读取的文件的大小和数组大小一致,创建字符数组缓冲区
byte[] buffer = new byte[1024 * 1024 * 5];//每次读取5M到内存中,然后存到该字节数组
//第三步,调用读取的方法
//第一个参数,存放字节的数组,
//第二个参数,开始往字节数组里写入的位置
//第三个参数,每次读取的字节大小
//返回值,返回本次实际读取到的有效字节数,比如读一个3.5M的文件,你虽然给的是5M的空间,实际上也只返回3.5
int r = fileStreamRead.Read(buffer, 0, buffer.Length);
//第四步,将字节数组中每一个元素按照指定的编码格式解码成想要的格式,这里我们转解码为字符串
//GetString第一个参数,要解码的数组,第二个参数,从数组的哪个字节开始解码,第三个参数,解码的长度,如果不写第二个和第三个参数,你读的文件小于你数组的长度(小于5M),他会把数组里剩下的也解码成空来填充
string str = Encoding.Default.GetString(buffer, 0, r);//如果Default读出来乱码可以换成UTF8比如Encoding.UTF8.GetString(buffer, 0, r);
//第五步,关闭数据流:
fileStreamRead.Close();
//第六步,释放流所占用的资源,GC垃圾回收器无法帮我们释放数据流
fileStreamRead.Dispose();
//输出
Console.WriteLine(str);
FileStream写入文件
这里先用来读写文本文件举例子
借用using帮助释放资源,这样就不用手动关闭流和释放流,简化流程
//第一步,创建FileStream的对象
using (FileStream fsWrite = new FileStream(@"C:\Users\Admin\Desktop\Test\new.txt", FileMode.OpenOrCreate, FileAccess.Write))
{
string str = "看我有没有把你覆盖";//准备写入的数据,不会覆盖文本里的内容
byte[] buffer = Encoding.Default.GetBytes(str);//UTF的编码格式写如:Encoding.UTF8.GetBytes(str);
//需要的参数和读取的参数差不多
fsWrite.Write(buffer, 0, buffer.Length);
}
Console.WriteLine("写入成功");
复制多媒体文件
using (FileStream fsRead = new FileStream(@"C:\Users\Admin\Desktop\Test\测试视频.wmv", FileMode.OpenOrCreate, FileAccess.Read))
{
using (FileStream fsWrite = new FileStream(@"C:\Users\Admin\Desktop\Test\new.wmv", FileMode.OpenOrCreate, FileAccess.Write))
{
//创建字符数组缓冲区
byte[] buffer = new byte[1024 * 1024 * 5];//5M
while (true)//读取的文件可能比较大,所以要循环读,每次都是读取5M
{
int r = fsRead.Read(buffer, 0, buffer.Length);
if (r == 0)//判断是否读取完毕
{
break;
}
//最后一次读取到的数据可能小于5M,所以这里用r比较好
fsWrite.Write(buffer, 0, r);
}
}
}
Console.WriteLine("复制成功");
StreamReader和StreamWriter
这个两个流是用于操作文本的文本流
StreamReader读取,读取文本的时候是一行一行的读取的
////Encoding.Default参数乱码的时候可以加,不乱码可以不加
using (StreamReader sRead = new StreamReader(@"C:\Users\Admin\Desktop\Test\new.txt", Encoding.Default))
{
////读取一行
//Console.WriteLine(sRead.ReadLine());
//读取全部行
while (!sRead.EndOfStream)//判断是否读到了这个流的结尾
{
Console.WriteLine(sRead.ReadLine());
}
}
StreamWriter写入
//在第二个参数后面放true表示不覆盖写入,默认是覆盖写入
using (StreamWriter sWrite=new StreamWriter(@"C:\Users\Admin\Desktop\Test\1.txt",true))
{
sWrite.Write("看我有没有把你覆盖");//第二个参数可以指定编码格式
}
Console.WriteLine("写入成功");
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构