当应用程序需要和磁盘上的文件打交道的时候,就有了流的概念。流就像架设在应用程序所在内存和磁盘之间的一个管道。

大致思路

→ 建立管道

//FileMode.Open打开现有文件,另外还有FileMode.Create, FileMode.Append
//FileAccess表示对文件的操作权限FileAccess.Read, FileAccess.Write, FileAccess.ReadWrite
//FileMode和FileAccess搭配使用
Stream pipe = new FileStream(@"C:\temp.png", FileMode.Open, FileAccess.Read);

→ 应用程序一般提供一个临时字节数组,用来传递数据

byte[] buffer = new byte[pipe.length];

→ 把流中的数据读到buffer数组中

//读到那里,从哪个地方开始读,读多少
//一般2GB一下的文件采用此方法
//返回读取到的字节数,当返回0表示读到了文件的结尾,流的终点
int bytesRead = pipe.Read(buffer, , (int)pipe.Length); 如果此时想把字节数组buffer显示出来,按如下: foreach(var item in buffer)
{
//显示成二进制
Console.Write(item.ToString(item, ));
}

→ 再把buffer中的字节保存到磁盘文件

Stream target = new FileStream(@"C:\target.png", FileMode.Create, FileAccess.Write);
target.Write(buffer, , buffer.Length);
target.Dispose();

分批复制

如果文件比较大,那就需要分批复制了。我们可以根据int bytesRead = pipe.Read(buffer, 0, (int)pipe.Length);中,bytesRead如果大于0就让循环,等于0说明已经读到源头流的结尾了。

//先定义临时字节数组的大小
int BufferSize = ; //源头流
Stream from = new FileStram(@"C:\bigger.png", FileModel.Open, FileAcess.Read); //目标流
Stream to = new FielStream(@"C:\biggertarget.png", FileMode.Create, FileAccess.Write); byte[] buffer = new byte[BufferSize];
int bytesRead;
do {
bytesRead = from.Read(buffer, , BufferSize);
to.Write(buffer, , BufferSize);
} while (bytesRead > ) from.Dispose();
to.Dispose();

流的家族成员

以上,了解了流的读取和写入,现在来了解下流的家族成员。

Stream是一个基类,抽象类,基本家族成员包括:

Stream
    FileStream
    MemoryStream
    NetworkStream
    
现实情况是有更多的流,比如加密流、压缩流等,这些流不仅有Stream的所有特征,还有自己的个性。这时候,用"装饰器模式"再好不过了。在这里,"装饰器模式"体现在:不仅继承Stream类,还引用Stream类。这些通过"装饰器模式"来实现的流包括:BufferedStream, DeflateStream, GZipStream, CryptoStream, AuthenticateStream.

流的操作有很多,.NET为我们封装了StreamReader和StreamWriter来对流进行操作,我们需要把流作为引用传入。基本用法如下:

FileStream from = new FileStream("C:\temp.txt", FileMode.Open, FileAccess.Read);
StreamReader reader = new StreamReader(from, Encoding.GetEncoding("GB2312"));
...
reader.Dispose();

以上,适合于读取或写入文本。

当涉及到二进制的读取和写入时,.NET为我们封装了BinaryReader和BinaryWriter。基本用法如下:

public class Book
{
public int Id{get;set;}
public string Name{get;set;}
public decimal Price{get;set;} private string saveFilePath = string.Empty; public Book(string saveFilePath)
{
this.saveFilePath = saveFilePath;
} public void SaveBook()
{
FileStream fs = new FileStream(this.saveFilePath, FileMode.Create, FileAccess.Write);
BinaryWriter writer = new BinaryWriter(fs);
writer.Write(this.Id);
writer.Write(this.Name);
writer.Write(this.Price);
writer.Dispose();
} publci void LoadBook()
{
FileStream fs = new FileStream(this.saveFilePath, FileMode.Open, FileAccess.Read);
BinaryReader reader = new BinaryReader(fs);
this.Id = reader.ReadInt32();
this.Name = reader.ReadString();
this.Price = reader.ReadDouble();
reader.Dispose();
} public override string ToString()
{
return string.Format("Id:{0}, Name: {1}, Price: {2}", this.Id, this.Name, this.Price);
}
} var book = new Book("C:\book.txt"){
Id = ,
Name = "",
Price =
};
book.SaveBook();

另外,不仅可以通过诸如new FileStream的构造函数创建流,.NET还为我们提供了产生流的静态帮助类和静态方法,比如File和FileInfo等,用法大致是:
FileStream fs = File.Create("C:\temp.jpg");

.NET中的流的更多相关文章

  1. [Node.js] Node.js中的流

    原文地址:http://www.moye.me/2015/03/29/streaming_in_node/ 什么是流? 说到流,就涉及到一个*nix的概念:管道——在*nix中,流在Shell中被实现 ...

  2. 理解Java中字符流与字节流的区别

    1. 什么是流 Java中的流是对字节序列的抽象,我们可以想象有一个水管,只不过现在流动在水管中的不再是水,而是字节序列.和水流一样,Java中的流也具有一个“流动的方向”,通常可以从中读入一个字节序 ...

  3. .NET客户端下载SQL Server数据库中文件流保存的大电子文件方法(不会报内存溢出异常)

    .NET客户端下载SQL Server数据库中文件流保存的大电子文件方法(不会报内存溢出异常) 前段时间项目使用一次性读去SQL Server中保存的电子文件的文件流然后返回给客户端保存下载电子文件, ...

  4. 谈一谈Java8的函数式编程(二) --Java8中的流

    流与集合    众所周知,日常开发与操作中涉及到集合的操作相当频繁,而java中对于集合的操作又是相当麻烦.这里你可能就有疑问了,我感觉平常开发的时候操作集合时不麻烦呀?那下面我们从一个例子说起. 计 ...

  5. Java中IO流的总结

    有关Java中IO流总结图 流分类 按方向分 输入流 输出流 按单位分 字节流 字符流 按功能分 节点流 处理流(过滤流) 其他 所有的流继承与这四类流:InputSteam.OutputStream ...

  6. java中有关流操作的类和接口

    一.java操作l流有关的类和接口 1.File 文件类 2.RandomAccessFile 随机存储文件类 3.InputStream 字节输入流 4.OutputStream 字节输出流 5.R ...

  7. ASP.NET Core SignalR中的流式传输

    什么是流式传输? 流式传输是这一种以稳定持续流的形式传输数据的技术. 流式传输的使用场景 有些场景中,服务器返回的数据量较大,等待时间较长,客户端不得不等待服务器返回所有数据后,再进行相应的操作.这时 ...

  8. node.js中stream流中可读流和可写流的使用

    node.js中的流 stream 是处理流式数据的抽象接口.node.js 提供了很多流对象,像http中的request和response,和 process.stdout 都是流的实例. 流可以 ...

  9. Java中IO流中的装饰设计模式(BufferReader的原理)

    本文粗略的介绍下JavaIO的整体框架,重在解释BufferReader/BufferWriter的演变过程和原理(对应的设计模式) 一.JavaIO的简介 流按操作数据分为两种:字节流与字符流. 流 ...

  10. mongoose中的流查询stream query

    mongoose中的流查询stream query,功能类似于php中的mysql_fetch_array,每次从集合中获取一条记录(文档) var cursor = Person.find({ oc ...

随机推荐

  1. UIWebView加载页面

    在页面中 加载了一个webView 当点击该webView的页面 需要获取webView中的url. 在push出来的另一个页面中,重新初始化一个webView加载 下面这个方法 在webView加载 ...

  2. 集合与Iterator

    Iterator模式 是遍历集合类的标准访问方法.为的是不暴露类的内部结构,将访问逻辑从集合类中抽象出来. 想循环遍历数组,链表等结构数据,客户端都必须事先知道集合的内部结构,访问代码和集合本身是紧耦 ...

  3. oracle sql优化笔记

    oracle优化一般分为:1.sql优化(现在oracle都会根据sql语句先进行必要的优化处理,这种应该用户不大了,但是像关联和嵌套查询肯定是和影响性能的) A.oracle的sql语句的条件是从右 ...

  4. UIMenuController 实现长按显示自定义菜单功能

    这段时间在集成使用融云聊天功能的时候,想自定义消息cell的长按的菜单,在网上查了查,这是根据 UIMenuController 实现的.具体代码如下,我是使用一个btn实现的 首先创建一个btn,并 ...

  5. Oracle DB 存储增强

    • 设置Automatic Storage Management (ASM)  快速镜像 再同步 • 使用ASM 首选镜像读取 • 了解可伸缩性和性能增强 • 设置ASM 磁盘组属性 • 使用SYSA ...

  6. 【转】python fabric实现远程操作和部署

    fabric title是开发,但是同时要干开发测试还有运维的活……为毛 task*3 不是 salary * 3 (o(╯□╰)o) 近期接手越来越多的东西,发布和运维的工作相当机械,加上频率还蛮高 ...

  7. python基础语法(2)

    2. 元组 tuple和list十分相似,但是tuple是不可变的,即不能修改tuple,元组通过圆括号中用逗号分割的项定义:支持索引和切片操作:可以使用 in 查看一个元素是否在tuple中.空元组 ...

  8. java web 资源地址写法

    前提:假设web应用test(工程名) webapps下面有一资源文件test.html 规则:在获取资源时一般使用的是相对路径,以符号/开头,而 / 代表什么取决于这个地址给谁使用.服务器使用时,/ ...

  9. Python模拟C++输出流

    看到一Python例子,挺有意思的,用Python模拟C++的输出流OStream.单纯只是玩. 原理: 利用Python __lshift__左移内建函数<<,调用时将输出内容,如果内容 ...

  10. 『TCP/IP详解——卷一:协议』读书笔记——06

    2013-08-20 14:41:01 2.8 最大传输单元MTU MTU,最大传输单元:以太网和802.3对数据帧的长度都有一个限制,其最大值分别是1500和1492字节.这个不同网络对应的传输上限 ...