转自:http://www.cnblogs.com/kissdodog/archive/2013/01/20/2868864.html

MemoryStream 是一个特例,MemoryStream中没有任何非托管资源,所以它的Dispose不调用也没关系。托管资源.Net会自动回收

MemoryStream继承自Stream类。内存流的好处是指针可以晃来晃去,也就是支CanSeek,Position,Seek()。任意读其中一段。

在内存流中有必要了解一下SeekOrigin枚举

枚举成员    成员值        描述

Begin                 指定流的开头。
Current 指定流内的当前位置。
End 指定流的结尾。

OK,记住了SeekOrigin枚举就来看下MemoryStream提供的属性与方法。

一、属性

CanRead     已重写。获取一个值,该值指示当前流是否支持读取。
CanSeek     已重写。获取一个值,该值指示当前流是否支持查找。
CanTimeout    获取一个值,该值确定当前流是否可以超时。(从 Stream 继承。)
CanWrite      已重写。获取一个值,该值指示当前流是否支持写入。
Capacity     获取或设置分配给该流的字节数。 这个是分配的字节数
Length       已重写。获取用字节表示的流长度。这个是真正占用的字节数。
Position      已重写。获取或设置流中的当前位置。
ReadTimeout    获取或设置一个值,该值确定流在超时前尝试读取多长时间。 (从 Stream 继承。)
WriteTimeout    获取或设置一个值,该值确定流在超时前尝试写入多长时间。 (从 Stream 继承。)

二、方法

BeginRead     开始异步读操作。 (从 Stream 继承。)
BeginWrite    开始异步写操作。 (从 Stream 继承。)
Close        关闭当前流并释放与之关联的所有资源(如套接字和文件句柄)。 (从 Stream 继承。)
CreateObjRef    创建一个对象,该对象包含生成用于与远程对象进行通信的代理所需的全部相关信息。 (从 MarshalByRefObject 继承。)
Dispose      已重载。
EndRead     等待挂起的异步读取完成。 (从 Stream 继承。)
EndWrite      结束异步写操作。 (从 Stream 继承。)
Flush        已重写。 重写 Stream.Flush 以便不执行任何操作。
GetBuffer     返回从其创建此流的无符号字节数组。 是会返回所有分配的字节,不管用没用到。
GetLifetimeService      检索控制此实例的生存期策略的当前生存期服务对象。 (从 MarshalByRefObject 继承。)
InitializeLifetimeService   获取控制此实例的生存期策略的生存期服务对象。 (从 MarshalByRefObject 继承。)
Read            已重写。 从当前流中读取字节块并将数据写入 buffer 中。 搞
了好久才弄明白Read()方法的含义,第一个参数,是读取到的内               容要输出到的字节数组,第二个参数是放在第一个参数即要
输出的数组的位置的偏移量,第三个参数是,要读取的字符数。
用               这个方法你可以任意读取一段需要的内存。注意,Read()方法是从当前流的Position属性的位置开始读,这就是
为什么很多人               测试的时候,刚刚写入内存的数据,Read()方法无法读取到内容的原因,因为刚刚写入内存之后,位置恰好是
在最后一位了。               Read()方法当然读不到。此方法强大之处在于,你可以从一个内存流中读出你想要的一个片段。
ReadByte           已重写。 从当前流中读取一个字节。
Seek            已重写。 将当前流中的位置设置为指定值。
SetLength          已重写。 将当前流的长度设为指定值。
Synchronized        在指定的 Stream 对象周围创建线程安全(同步)包装。 (从 Stream 继承。)
ToArray           将整个流内容写入字节数组,而与 Position 属性无关。
Write            已重写。 使用从缓冲区读取的数据将字节块写入当前流。 同样注意下,第二个参数是第一个参数数组的偏移量就可以了。
WriteByte         已重写。 将一个字节写入当前流中的当前位置。
WriteTo          将此内存流的整个内容写入另一个流中。

以下给出使用示例代码:

        static void Main(string[] args)
{
//属性测试
MemoryStream ms = new MemoryStream();
Console.WriteLine(ms.CanRead); //True 内存流可读
Console.WriteLine(ms.CanSeek); //True 内存流支持查找,指针移来移去的查找
Console.WriteLine(ms.CanTimeout); //False 内存流不支持超时
Console.WriteLine(ms.CanWrite); //True 内存流可写 Console.WriteLine(ms.Capacity); //0 分配给该流的字节数
byte[] bytes = Encoding.UTF8.GetBytes("abcdedcba");
ms.Write(bytes, , bytes.Length); //已将一段文本写入内存
Console.WriteLine(ms.Capacity); //256 再次读取为文本流分配的字节数已经变成了256,看来内存流是根据需要的多少来分配的
Console.WriteLine(ms.Length); //9 这个是流长度,通常与英文的字符数一样,真正占用的字节数。 Console.WriteLine(ms.Position); //9 流当前的位置,该属性可读可设置 //Console.WriteLine(ms.ReadTimeout); 由于流不支持超时,此属性如果读取或者设置的话会报错
//Console.WriteLine(ms.WriteTimeout); 由于流不支持超时,此属性如果读取或者设置的话会报错 //方法测试
byte[] byte1 = ms.GetBuffer(); //返回无符号字节数组 差点被忽悠了,无符号字节数组 其实就是byte(0~255),有符号字节sbyte(-128~127)
string str1 = Encoding.UTF8.GetString(byte1);
Console.WriteLine(str1); //输出 abcdedcba ms.Seek(, SeekOrigin.Current); //设置当前流正在读取的位置 为开始位置即从0开始
//从内存中读取一个字节
int i = ms.ReadByte();
Console.WriteLine(i); //输出99
byte[] bytes3 = ms.ToArray();
foreach (byte b in bytes3)
{
Console.Write(b + "-");//用于对比 输出 97-98-99-100-101-100-99-98-97- 可以看到 0,1,2第二位刚好是99
} MemoryStream ms2 = new MemoryStream();
byte[] bytes6 = Encoding.UTF8.GetBytes("abcde");
ms2.Write(bytes6, , bytes6.Length);
Console.WriteLine(ms2.Position); //输出5 写完之后流的位置就到了最后,因此想用read读取必须加下面这一行代码。 //ms2.Seek(0, SeekOrigin.Begin); //想要用Read方法读取完整的流,必须设置当前位置,Read是从Position的位置开始读。
ms2.Position = ; //Read是从当前位置开始读,这行代码和上面一行意义一样。
byte[] byteArray = new byte[] { , , , , }; //99是经过YTF8解码之后是 n
ms2.Read(byteArray, , ); //读取一个字节,byteArray的第一个元素中,(注意从0开始)
Console.WriteLine(Encoding.UTF8.GetString(byteArray)); //nnann
//ms2.Read(byteArray, 2, 2);
//Console.WriteLine(Encoding.UTF8.GetString(byteArray)); //nnabn //当超出接收数组总长度的时候,后面的元素会被移开 //设置当前流的长度
Console.WriteLine(ms.Length); //输出9 当前流的长度是9
ms.SetLength();
Console.WriteLine(ms.Length); //输出20
foreach (byte b in ms.ToArray()) //将流的内容也就是内存中的内容转换字节数组
{
Console.Write(b + "-"); //输出 97-98-99-100-101-100-99-98-97-0-0-0-0-0-0-0-0-0 由于设置了长度,因此空的自动补0
}
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray())); //输出 abcdedcba 虽然长度变长了,但是没影响读取数据 MemoryStream ms1 = new MemoryStream();
byte[] bytes4 = ms1.ToArray();
Console.WriteLine("此内存流并没有写入数据(Write)" + Encoding.UTF8.GetString(bytes4));//输出 此内存流并没有写入数据(Write) 因为内存为空 //下面来一个指定位置的写入
MemoryStream ms3 = new MemoryStream();
byte[] bytesArr = Encoding.ASCII.GetBytes("abcdefg");
ms3.Write(bytesArr, , bytesArr.Length);
ms3.Position = ;
ms3.WriteByte(); //97代表的是a 这段代码的意思是,将原先第二个的c替换为a
string str = Encoding.ASCII.GetString(ms3.ToArray());
Console.WriteLine(str); //输出 abacdefg byte[] byteArr1 = Encoding.ASCII.GetBytes("kk");
ms3.Position = ;
ms3.Write(byteArr1, , byteArr1.Length);
Console.WriteLine(Encoding.UTF8.GetString(ms3.ToArray())); //abadkkg //从第4位替换掉了两个字节为KK Console.ReadKey();
}

MemoryStream类的更多相关文章

  1. (转载)C#使用MemoryStream类读写内存

    MemoryStream和BufferedStream都派生自基类Stream,因此它们有很多共同的属性和方法,但是每一个类都有自己独特的用法.这两个类都是实现对内存进行数据读写的功能,而不是对持久性 ...

  2. C#使用MemoryStream类读写内存

    MemoryStream和BufferedStream都派生自基类Stream,因此它们有很多共同的属性和方法,但是每一个类都有自己独特的用法.这两个类都是实现对内存进行数据读写的功能,而不是对持久性 ...

  3. C#中MemoryStream类的介绍

    MemoryStream位于System.IO命名空间,为系统内存提供流式的读写操作.常作为其他流数据交换时的中间对象操作. 1.MemoryStream类封装一个字节数组,在构造实例时可以使用一个字 ...

  4. MemoryStream类读写内存

    和FileStream一样,MemoryStream和BufferedStream都派生自基类Stream,因此它们有很多共同的属性和方法,但是每一个类都有自己独特的用法.这两个类都是实现对内存进行数 ...

  5. c# MemoryStream 类

  6. 文件读写(三)利用FileStream类操作字节数组byte[]、BinaryFormatter、内存流MemoryStream

    一.Stream类概述 在.NET Framework中,文件和流是有区别的.文件是存储在磁盘上的数据集,它具有名称和相应的路径.当打开一个文件并对其进行读/写时,该文件就称为流(stream).但是 ...

  7. [C#]MemoryStream.Dispose之后,为什么仍可以ToArray()?

    目录 概述 MemoryStream分析 总结 概述 事件起因,一哥们在群里面贴出了类似下面这样的一段代码: class Program { static void Main(string[] arg ...

  8. stream,file,filestream,memorystream简单的整理

    一.Stream 什么是stream?(https://www.cnblogs.com/JimmyZheng/archive/2012/03/17/2402814.html#no8) 定义:提供字节序 ...

  9. Stream、FileStream、MemoryStream的区别

    1.Stream:流,在msdn的定义:提供字节序列的一般性视图,Stream提供了读写流的方法是以字节的形式从流中读取内容.而我们经常会用到从字节流中读取文本或者写入文本,微软提供了StreamRe ...

随机推荐

  1. .Net 中表达式的转换

    .Net 中表达式的转换 如: a>0  && (c>a || a <b ) || (a>b || c>1)    转换后  (((a > 0) a ...

  2. asp图片化电话号码,避免蜘蛛之类爬走用户隐私

    作用:将页面中的电话号码生成图片格式.挺多的分类信息类网站使用这个功能.不用真正的生成图片.原理类似验证码,挺不错的. <% Call Com_CreatValidCode(Request.Qu ...

  3. JAVA 中两种判断输入的是否是数字的方法__正则化_

    JAVA 中两种判断输入的是否是数字的方法 package t0806; import java.io.*; import java.util.regex.*; public class zhengz ...

  4. MySql数据库的导入_命令工具

    一.如何导入别人已经建好的数据库 create database goods use goods source E:\goods.sql (绝对路径) 这样就导入了指定的数据库到本机电脑 二.任何数据 ...

  5. LaTeX中用BibTex管理参考文献

    BibTeX 是一种用来规范参考文献列表的一种文献管理软件,定义了一种比较通用的管理文献的格式, 用于协调LaTeX的参考文献处理. BibTeX 使用数据库的的方式来管理参考文献. BibTeX 文 ...

  6. ###学习《C++ Primer》- 4

    点击查看Evernote原文. #@author: gr #@date: 2014-10-16 #@email: forgerui@gmail.com Part 4: STL关联容器(第11章) 一. ...

  7. 用pelican搭建完美博客

    前面有文章介绍本站采用了Python编写的Pelican静态生成博客系统, 之所以没有使用当前很火的Jekyll, 是因为它是Ruby编写, 而我又对Ruby没有啥兴趣, 所以还是选择了使用了我熟悉的 ...

  8. (转).Net平台开源作业调度框架Quartz.Net

    Quartz.NET介绍: Quartz.NET是一个开源的作业调度框架,是OpenSymphony 的 Quartz API的.NET移植,它用C#写成,可用于winform和asp.net应用中. ...

  9. 十分钟搭建个人网站:Jekyll主题BoHu

    最近花了三天时间制作了我的第一个jekyll theme--BoHu.一款知乎风格的模板,使用jekyll模板引擎,十分钟就能搭建属于你自己的静态博客网站. 本主题的特征为: 知乎风格 分页导航使用的 ...

  10. 一篇关于学C++的感想(拿来与大家分享)

    学计算机的如果你有耐心看下去,我敢保证这绝对是一种收获 期待爱 大师提醒: 计算机专业不是学编程,而是懂得计算机的工作原理,以及和计算机相关的学科技术.一个高手不必懂得编程,coder是最底层的人物, ...