MemoryStream类简介
MemoryStream的属性与方法
MemoryStream属性
MemoryStream ms = new MemoryStream(); //创建一个内存流
Console.WriteLine("ms是否可读:{0}",ms.CanRead); //获取一个值,指示ms是否可读
Console.WriteLine("ms是否可查找:{0}",ms.CanSeek); //获取一个值,指示ms是否可查找
Console.WriteLine("ms是否可写:{0}",ms.CanWrite); //获取一个值,指示ms是否可写
Console.WriteLine("ms是否支持超时:{0}",ms.CanTimeout); //获取一个值,指示ms是否支持超时
Console.WriteLine("更改之前的系统缓冲区大小:{0}",ms.Capacity); // 获取系统分配的缓冲区大小 Console.WriteLine("流的长度:{0}",ms.Length); //获取流的长度
ms.Capacity = 1024; //以字节为单位 1KB大小 capacity可读可写
Console.WriteLine("更改之后的系统缓冲区大小:{0}",ms.Capacity); ms.ReadTimeout = 100; // 设置内存流超时前读取的时间,单位是毫秒
ms.WriteTimeout = 100;// 设置内存流超时前写入的时间
Console.ReadKey();
MemoryStream的方法
BeginRead 开始异步读操作。(从 Stream 继承)
BeginWrite 开始异步写操作。(从 Stream 继承)
Close 关闭当前流并释放与之关联的所有资源(如套接字和文件句柄)(从 Stream 继承)
Dispose 释放资源(从 Stream 继承)
EndRead 等待挂起的异步读取完成。(从 Stream 继承)
EndWrite 结束异步写操作。(从 Stream 继承)
Flush 重写 Stream.Flush 以便不执行任何操作
GetBuffer 返回从其创建此流的无符号字节数组。 是会返回所有分配的字节,不管用没用到。
Read 从当前流中读取字节块并将数据写入 buffer 中。注意,Read()方法是从当前流的Position属性的位置开始读,这就是为什么很多人测试的时候,刚刚写入内存的数据,Read()方法无法读取到内容的原因,因为刚刚写入内存之后,位置恰好是在最后一位了。Read()方法当然读不到。此方法强大之处在于,你可以从一个内存流中读出你想要的一个片段。
ReadByte 从当前流中读取一个字节。(注意是按字节读取) (从 Stream 继承)
Seek 将当前流中的位置设置为指定值。(从 Stream 继承)
SetLength 将当前流的长度设为指定值。 (从 Stream 继承)
Synchronized 在指定的 Stream 对象周围创建线程安全(同步)包装。(从 Stream 继承)
ToArray 将整个流内容写入字节数组,而与 Position 属性无关。
Write 使用从缓冲区读取的数据将字节块写入当前流。 注意下,第二个参数是第一个参数数组的偏移量就可以了。
WriteByte 将一个字节写入当前流中的当前位置。 (从 Stream 继承)
WriteTo 将此内存流的整个内容写入另一个流中。(常用在使用内存流向其他的流转换,如文件流)。
方法测试实例
注意三点:
一:所谓的缓冲区通常都是由字节数组构成,MemoryStream可以方便快捷的使用字节数组进行读和写。
二:使用MemoryStream时要注意流的索引位置,也就是Position属性,如刚刚写入数据,那么Position的位置在数据的最后,如果不进行设置,是无法使用Read和ReadByte读取流的数据的。
三:注意将字符串转换成字节数组和将字节数组转化成字符串的思路,这是自己缺失的一部分(使用相同的对象进行转换)
MemoryStream ms = new MemoryStream();
byte[] buffer = Encoding.UTF8.GetBytes("shileizhenshiyigedahaoren"); //一般缓冲区都是由字节数组构成
ms.Write(buffer,0,6); //从缓冲区读取数据写入到流中,
byte[] result1 = ms.GetBuffer(); //返回写入内存流的原流数据
string turnStr = Encoding.UTF8.GetString(result1); //将字节数组转换成字符串。
Console.WriteLine(turnStr);
ms.Seek(4,SeekOrigin.Begin); //将流的当前位置设置为开始的位置
int i = ms.ReadByte(); //读取一个字节,如果达到了流的末尾则为-1,返回字节的ASCII码
Console.WriteLine("流的当前位置:{0}",i.ToString());
byte[] result2 = ms.ToArray(); //流返回一个字节数组,缓冲区, 类似GetBuffer
foreach (var item in result2)
{
Console.Write(item.ToString() + "-");
}
MemoryStream ms2 = new MemoryStream();
byte[] buffer2 = Encoding.UTF8.GetBytes("这个世界真的很美好"); //utf-8中,一个汉字三个字节
ms2.Write(buffer2,0,buffer2.Length); //参数1写入的数据源,参数2数据源的开始索引,参数3写入长度
Console.WriteLine("\n"+ms2.Position); //position可以理解为ms中的指针,写完数据后,指针在最后一位
int j = ms2.ReadByte(); //索引Position在最后一位,所以返回的值为-1,表示在最后
Console.WriteLine("写入数据后当前指针指向的值:{0}", j.ToString());
ms2.Position = 0; //设置索引在第一位
int k = ms2.ReadByte();
Console.WriteLine("改变指针后的值:{0}", k.ToString());
Console.ReadKey();
MemoryStream实例
利用XmlWritter与MemoryStream写数据,实现了MemoryStream和FileStream的转换,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
namespace test001
{
class Program
{
static void Main(string[] args)
{
MemoryStream ms = new MemoryStream();
using (ms) // 确保程序在代码段结束的时候dispose掉ms
{
XmlWriter writer = XmlWriter.Create(ms); //创建一个Xmlwriter对象
using (writer) //确保在程序在代码段结束时调用Dispose
{
writer.WriteStartDocument(true); //写入Xml头
writer.WriteStartElement("Content"); //写入元素
writer.WriteStartAttribute("Test"); //写入属性
writer.WriteValue("往事都随风!"); //写入属性值
writer.Flush(); //释放缓冲
Console.WriteLine("此时内容使用量:{0}KB \n 该memoryStream已经使用容量:{1}Byte \n 默认容量{2}", Math.Round((double)ms.Length, 4), ms.Capacity, GC.GetTotalMemory(false) / 1024);
Console.WriteLine("重定位MemoryStream的位置{0}", ms.Position); //输出ms的现在所在的位置
ms.Seek(7, SeekOrigin.Current);
Console.WriteLine("重定位后MemoryStream的位置{0}", ms.Position);
writer.WriteStartElement("Content2");
writer.WriteStartAttribute("Test");
writer.WriteValue("不想随风了!");
writer.WriteEndElement();
writer.WriteEndElement();
writer.Flush(); //释放资源
Console.WriteLine("此时内容使用量:{0}KB \n 该memoryStream已经使用容量:{1}Byte \n 默认容量{2}", Math.Round((double)ms.Length, 4), ms.Capacity, GC.GetTotalMemory(false) / 1024);
string path = @"G:\test.xml";
FileStream fs = new FileStream(path, FileMode.OpenOrCreate);
ms.WriteTo(fs); //把ms写入到fs中去 writeto
fs.Flush();
Console.ReadKey();
}
}
}
}
}