C#MemoryStream类案例详解
MemoryStream位于System.IO命名空间,为系统内存提供流式的读写操作。常作为其他流数据交换时的中间对象操作。
1. MemoryStream类封装⼀个字节数组,在构造实例时可以使⽤⼀个字节数组作为参数,但是数组的长度⽆法调整。使⽤
默认⽆参数构造函数创建实例,可以使⽤Write⽅法写⼊,随着字节数据的写⼊,数组的⼤⼩⾃动调整。
2. 在对MemoryStream类中数据流进⾏读取时,可以使⽤ek⽅法定位读取器的当前的位置,可以通过指定长度的数组⼀
了不起的盖茨比原声
次性读取指定长度的数据。ReadByte⽅法每次读取⼀个字节,并将字节返回⼀个整数值。
3. UnicodeEncoding类中定义了Unicode中UTF-16编码的相关功能。通过其中的⽅法将字符串转换为字节,也可以将字节
elegance
转换为字符串。
MemoryStream 是⼀个特例,MemoryStream中没有任何⾮托管资源,所以它的Dispo不调⽤也没关系。托管资源.Net会⾃动回收
MemoryStream继承⾃Stream类。内存流的好处是指针可以晃来晃去,也就是⽀CanSeek,Position,Seek()。任意读其中⼀段。
在内存流中有必要了解⼀下SeekOrigin枚举
枚举成员成员值描述
Begin0指定流的开头。
Current1指定流内的当前位置。
End2指定流的结尾。
graduatesMemoryStream提供的属性与⽅法:
⼀、属性
CanRead 已重写。获取⼀个值,该值指⽰当前流是否⽀持读取。
CanSeek 已重写。获取⼀个值,该值指⽰当前流是否⽀持查找。
CanTimeout 获取⼀个值,该值确定当前流是否可以超时。(从 Stream 继承。)
CanWrite 已重写。获取⼀个值,该值指⽰当前流是否⽀持写⼊。
Capacity 获取或设置分配给该流的字节数。这个是分配的字节数
Length 已重写。获取⽤字节表⽰的流长度。这个是真正占⽤的字节数。
Position 已重写。获取或设置流中的当前位置。
ReadTimeout 获取或设置⼀个值,该值确定流在超时前尝试读取多长时间。(从 Stream 继承。)
WriteTimeout 获取或设置⼀个值,该值确定流在超时前尝试写⼊多长时间。(从 Stream 继承。)
⼆、⽅法
BeginRead 开始异步读操作。(从 Stream 继承。)
BeginWrite 开始异步写操作。(从 Stream 继承。)
Clo 关闭当前流并释放与之关联的所有资源(如套接字和⽂件句柄)。(从 Stream 继承。)CreateObjRef 创建⼀个对象,该对象包含⽣成⽤于与远程对象进⾏通信的代理所需的全部相关信息。(从MarshalByRefObject 继承。)
Dispo 已重载。
EndRead 等待挂起的异步读取完成。(从 Stream 继承。)
EndWrite 结束异步写操作。(从 Stream 继承。)
汉翻英在线Flush 已重写。重写 Stream.Flush 以便不执⾏任何操作。
GetBuffer 返回从其创建此流的⽆符号字节数组。是会返回所有分配的字节,不管⽤没⽤到。GetLifetimeService 检索控制此实例的⽣存期策略的当前⽣存期服务对象。(从 MarshalByRefObject 继承。)InitializeLifetimeService 获取控制此实例的⽣存期策略的⽣存期服务对象。(从 MarshalByRefObject 继承。)
Read 已重写。从当前流中读取字节块并将数据写⼊ buffer 中。搞了好久才弄明⽩Read()⽅法的含义,第⼀个参数,是读取到的内容要输出到的字节数组,第⼆个参数是放在第⼀个参数即要输出的数组的位置的偏移量,第三个参数是,要读取的字符数。⽤这个⽅法你可以任意读取⼀段需要的内
存。注意,Read()⽅法是从当前流的Position属性的位置开始读,这就是为什么很多⼈测试的时候,刚刚写⼊内存的数据,Read()⽅法⽆法读取到内容的原因,因为刚刚写⼊内存之后,位置恰好是在最后⼀位了。Read()⽅法当然读不到。此⽅法强⼤之处在于,你可以从⼀个内存流中读出你想要的⼀个⽚段。
ReadByte 已重写。从当前流中读取⼀个字节。
Seek 已重写。将当前流中的位置设置为指定值。
SetLength 已重写。将当前流的长度设为指定值。socks的音标
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); //Fal 内存流不⽀持超时
Console.WriteLine(ms.CanWrite); //True 内存流可写
Console.WriteLine(ms.Capacity); //0 分配给该流的字节数
byte[] bytes = Encoding.UTF8.GetBytes("abcdedcba");
ms.Write(bytes, 0, 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(2, 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, 0, bytes6.Length);
Console.WriteLine(ms2.Position); //输出5 写完之后流的位置就到了最后,因此想⽤read读取必须加下⾯这⼀⾏代码。
//ms2.Seek(0, SeekOrigin.Begin); //想要⽤Read⽅法读取完整的流,必须设置当前位置,Read是从Position的位置开始读。
ms2.Position = 0; //Read是从当前位置开始读,这⾏代码和上⾯⼀⾏意义⼀样。
byte[] byteArray = new byte[5] { 110, 110, 110, 110, 110 }; //99是经过YTF8解码之后是 n
ms2.Read(byteArray, 2, 1); //读取⼀个字节,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(20);
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();
karate
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, 0, bytesArr.Length);
ms3.Position = 2;
ms3.WriteByte(97); //97代表的是a 这段代码的意思是,将原先第⼆个的c替换为a
string str = Encoding.ASCII.GetString(ms3.ToArray());
Console.WriteLine(str); //输出 abacdefg
byte[] byteArr1 = Encoding.ASCII.GetBytes("kk");
ms3.Position = 4;drillmyhole
初中英语教学计划
ms3.Write(byteArr1, 0, byteArr1.Length);
Console.WriteLine(Encoding.UTF8.GetString(ms3.ToArray())); //abadkkg //从第4位替换掉了两个字节为KK
Console.ReadKey();
}
接下来实现数据类的转换:
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
public class DataSwitch
{
/// <summary>
/// 数据类对象转成字节流
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
/// //MemoryStream: 创建其⽀持存储区为内存的流。
//IFormatter : 提供将序列化对象格式化的功能。
public static byte[] ObjectToBytes(object obj)
{
using (MemoryStream ms = new MemoryStream())
{
/
/ //以⼆进制格式将对象或整个连接对象图形序列化和反序列化。
IFormatter formatter = new BinaryFormatter();
//把字符串以⼆进制放进memStream中
formatter.Serialize(ms, obj);
//返回从其创建此流的⽆符号字节数组。是会返回所有分配的字节,不管⽤没⽤到。
2013考研政治真题返回⽆符号字节数组,⽆符号字节数组其实就是byte(0~255),有符号字节sbyte(-128~127)
return ms.GetBuffer();
}
}
/// <summary>
/// 字节流转成数据类对象
splitcond
/
// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
public static object BytesToObject(byte[] bytes)
{
using (MemoryStream ms = new MemoryStream(bytes))
{
// //以⼆进制格式将对象或整个连接对象图形序列化和反序列化。
IFormatter formatter = new BinaryFormatter();
//把字符串以⼆进制放进memStream中
return formatter.Derialize(ms);
}
}
}
到此这篇关于C# MemoryStream类案例详解的⽂章就介绍到这了,更多相关C# MemoryStream类内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!