当前位置: 首页 > news >正文

唐河永琚建筑公司网站湖南城乡建设网站

唐河永琚建筑公司网站,湖南城乡建设网站,专业郑州网站建设,谷歌网站提交MemoryStream 目录#xff1a; 1 简单介绍一下MemoryStream 2 MemoryStream和FileStream的区别 3 通过部分源码深入了解下MemoryStream 4 分析MemorySteam最常见的OutOfMemory异常 5 MemoryStream 的构造 6 MemoryStream 的属性 7 MemoryStream 的方法 8 MemoryStream 简单示例…MemoryStream 目录 1 简单介绍一下MemoryStream 2 MemoryStream和FileStream的区别 3 通过部分源码深入了解下MemoryStream 4 分析MemorySteam最常见的OutOfMemory异常 5 MemoryStream 的构造 6 MemoryStream 的属性 7 MemoryStream 的方法 8 MemoryStream 简单示例 :  XmlWriter中使用MemoryStream 9 MemoryStream 简单示例 自定义一个处理图片的HttpHandler 10 本章总结       简单介绍一下MemoryStream MemoryStream是内存流,为系统内存提供读写操作由于MemoryStream是通过无符号字节数组组成的可以说MemoryStream的性能可以 算比较出色所以它担当起了一些其他流进行数据交换时的中间工作同时可降低应用程序中对临时缓冲区和临时文件的需要,其实MemoryStream 的重要性不亚于FileStream在很多场合我们必须使用它来提高性能   MemoryStream和FileStream的区别 前文中也提到了FileStream主要对文件的一系列操作属于比较高层的操作但是MemoryStream却很不一样它更趋向于底层内存的操作这样 能够达到更快的速度和性能也是他们的根本区别很多时候操作文件都需要MemoryStream来实际进行读写最后放入到相应的FileStream中, 不仅如此在诸如XmlWriter的操作中也需要使用到MemoryStream提高读写速度   通过部分源码深入了解下MemoryStream  由于篇幅关系本篇无法详细说明其源码还请大家海涵这里我就简单介绍下Write()方法的源码 public override void Write(byte[] buffer, int offset, int count) {if (!_isOpen) __Error.StreamIsClosed();if (!_writable) __Error.WriteNotSupported();if (buffernull)throw new ArgumentNullException(buffer, Environment.GetResourceString(ArgumentNull_Buffer));if (offset 0)throw new ArgumentOutOfRangeException(offset, Environment.GetResourceString(ArgumentOutOfRange_NeedNonNegNum));if (count 0)throw new ArgumentOutOfRangeException(count, Environment.GetResourceString(ArgumentOutOfRange_NeedNonNegNum));if (buffer.Length - offset count)throw new ArgumentException(Environment.GetResourceString(Argument_InvalidOffLen));int i _position count;// Check for overflowif (i 0)throw new IOException(Environment.GetResourceString(IO.IO_StreamTooLong));if (i _length) {bool mustZero _position _length;if (i _capacity) {bool allocatedNewArray EnsureCapacity(i);if (allocatedNewArray)mustZero false;}if (mustZero)Array.Clear(_buffer, _length, i - _length);_length i;}if (count 8){int byteCount count;while (--byteCount 0)_buffer[_position byteCount] buffer[offset byteCount];}elseBuffer.InternalBlockCopy(buffer, offset, _buffer, _position, count);_position i;return;} 关于MemoryStream的源码大家可以自己学习这里主要分析下MemoryStream最关键的Write()方法自上而下最开始的一系列判断大家很容易看明白 以后对有可能发生的异常应该了如指掌了吧判断后会取得这段数据的长度 int i_positioncount 接下来会去判断该数据的长度是否超过了该流的长度 如果超过再去检查是否在流的可支配容量(字节)之内(注意下EnsureCapacity方法该方法会自动扩容stream的容量但是前提条件是你使用了memoryStream 的第二个构造函数也就是带有参数是Capaciy)如果超过了流的可支配容量则将尾巴删除将超过部分的数据清除,接下来大家肯定会问为什么要判断count8, 其实8这个数字在流中很关键个人认为微软为了性能需要而这样写当字节小于8时则一个个读当字节大于八时则用block拷贝的方式在这个范围内递减循环 将数据写入流中的缓冲_buffer中这个缓冲_buffe是memoryStream的一个私有byte数组类型流通过读取外部byte数据放入内部那个缓冲buffer中如果流 的长度超过了8则用Buffer.InternalBloackCopy方法进行数组复制,不同于Array.Copy 前者是采用内存位移而非索引位移所以性能上有很大的提升。其实 这个方法的原形是属于c中的。   分析MemorySteam最常见的OutOfMemory异常 先看下下面一段很简单的测试代码 //测试byte数组 假设该数组容量是256Mbyte[] testBytesnew byte[256*1024*1024];MemoryStream ms new MemoryStream();using (ms){for (int i 0; i 1000; i){try{ms.Write(testBytes, 0, testBytes.Length);}catch{Console.WriteLine(该内存流已经使用了{0}M容量的内存,该内存流最大容量为{1}M,溢出时容量为{2}M, GC.GetTotalMemory(false) / (1024 * 1024),//MemoryStream已经消耗内存量ms.Capacity / (1024 * 1024), //MemoryStream最大的可用容量ms.Length / (1024 * 1024));//MemoryStream当前流的长度容量break;}}}Console.ReadLine(); 由于我们设定了一个256M的byte有点恐怖看下溢出时的状态 从输出结果看MemoryStream默认可用最大容量是512M  发生异常时正好是其最大容量聪明的你肯定会问如果同时使用2个MemoryStream甚至于多个内存 是怎么分配的很好还是用代码来看下输出结果可以明显看出内存平均分给了2个MemoryStream但是最大容量还是512M 但是问题来了假设我们需要操作比较大的文件该怎么办呢?其实有2种方法能够搞定一种是前文所说的分段处理我们将byte数组分成等份进行 处理还有一个方法便是尽量增加MemoryStream的最大可用容量字节我们可以在声明MemoryStream构造函数时利用它的重载版本 MemoryStream(int capacity) 到底怎么使用哪种方法比较好呢其实笔者认为具体项目具体分析前者分段处理的确能够解决大数据量操作的问题但是牺牲了性能和时间多线程暂 时不考虑后者可以得到性能上的优势但是其允许的最大容量是 int.MAX所以无法给出一个明确的答案大家在做项目按照需求自己定制即可最关键 的还是要取到性能和开销的最佳点位          还有一种更恶心的溢出方式往往会让大家抓狂就是不定时溢出就是MemoryStream处理的文件可能只有40M或更小时也会发生OutOfMemory 的异常关于这个问题终于在老外的一篇文章中得到了解释运气不错陈彦铭大哥在他的博客中正好翻译了下免去我翻译的工作^^,由于这个牵涉到 windows的内存机制包括 内存页进程的虚拟地址空间等比较复杂所以大家看他的这篇文章前我先和大家简单介绍下页和进程的虚拟地址 内存页内存页分为文件页和计算页内存中的文件页是文件缓存区即文件型的内存页用于存放文件数据的内存页也称永久页作用在于读写文件时可以减少对磁盘的访问如果它的大小 设置得太小会引起系统频繁地访问磁盘增加磁盘I/O设置太大会浪费内存资源。内存中的计算页也称为计算型的内存页主要用于存放程序代码和临 时使用的数据 进程的虚拟地址每一个进程被给予它的非常私有的虚拟地址空间。对于32位的进程地址空间是4G因为一个32位指针能够有从0x00000000到0xffffffff之 间的任意值。这个范围允许指针有从4294967296个值的一个覆盖了一个进程的4G范围。对于64位进程地址空间是16eb因为一个64位指针能够指向 18,446,744,073,709,551,616个值中的一个覆盖一个进程的16eb范围。这是十分宽广的范围。 上述概念都来自windows核心编程 这本书其实这本书对我们程序员来说很重要对于内存的操作本人也是小白看来这本书非买不可了。。。。   MemoryStream 的构造 MemoryStream() MemoryStream 允许不带参数的构造   MemoryStream(byte[] byte) Byte数组是包含了一定的数据的byte数组这个构造很重要初学者或者用的不是很多的程序员会忽略这个构造导致后面读取或写入数据时发现memoryStream中 没有byte数据会导致很郁闷的感觉,大家注意下就行有时也可能无需这样因为很多方法返回值已经是MemoryStream了   MemoryStream(int capacity) 这个是重中之重为什么这么说呢我在本文探讨关于OutOfMemory异常中也提到了如果你想额外提高MemoryStream的吞吐量(字节)也只能靠这个方法提升 一定的吞吐量最多也只能到int.Max,这个方法也是解决OutOfMemory的一个可行方案   MemoryStream(byte[] byte, bool writeable) Writeable参数定义该流是否可写   MemoryStream(byte[] byte, int index, int count) Index 参数定义从byte数组中的索引index Count  参数是获取的数据量的个数   MemoryStream(byte[] byte,int index, int count, bool writeable, bool publiclyVisible) publiclyVisible 参数表示true 可以启用 GetBuffer方法它返回无符号字节数组流从该数组创建否则为 false大家一定觉得这很难理解别急下面的方法中 我会详细讲下这个东东    MemoryStream 的属性 Memory 的属性大致都是和其父类很相似这些功能在我的这篇中已经详细讨论过所以我简单列举一下其属性   其独有的属性: Capacity:这个前文其实已经提及它表示该流的可支配容量字节非常重要的一个属性   MemoryStream 的方法 对于重写的方法这里不再重复说明大家可以参考我写的第一篇 以下是memoryStream独有的方法 virtual byte[] GetBuffer() 这个方法使用时需要小心因为这个方法返回无符号字节数组也就是说即使我只输入几个字符例如”HellowWorld”我们只希望返回11个数据就行 可是这个方法会把整个缓冲区的数据包括那些已经分配但是实际上没有用到的字节数据都返回出来如果想启用这个方法那必须使用上面最后一个构 造函数将publiclyVisible属性设置成true就行这也是上面那个构造函数的作用所在   virtual void WriteTo(Stream stream) 这个方法的目的其实在本文开始时讨论性能问题时已经指出memoryStream常用起中间流的作用 所以读写在处理完后将内存流写入其他流中    简单示例 XmlWriter中使用MemoryStream /// summary/// 演示在xmlWriter中使用MemoryStream/// /summarypublic static void UseMemoryStreamInXMLWriter(){MemoryStream ms new MemoryStream();using (ms){//定义一个XMLWriterusing (XmlWriter writer XmlWriter.Create(ms)){//写入xml头writer.WriteStartDocument(true);//写入一个元素writer.WriteStartElement(Content);//为这个元素新增一个test属性writer.WriteStartAttribute(test);//设置test属性的值writer.WriteValue(逆时针的风);//释放缓冲这里可以不用释放但是在实际项目中可能要考虑部分释放对性能带来的提升writer.Flush();Console.WriteLine(此时内存使用量为:{2}KB,该MemoryStream的已经使用的容量为{0}byte,默认容量为{1}byte,Math.Round((double)ms.Length, 4), ms.Capacity,GC.GetTotalMemory(false)/1024);Console.WriteLine(重新定位前MemoryStream所在的位置是{0},ms.Position);//将流中所在的当前位置往后移动7位相当于空格ms.Seek(7, SeekOrigin.Current);Console.WriteLine(重新定位后MemoryStream所在的位置是{0}, ms.Position);//如果将流所在的位置设置为如下所示的位置则xml文件会被打乱//ms.Position 0;writer.WriteStartElement(Content2);writer.WriteStartAttribute(testInner);writer.WriteValue(逆时针的风Inner);writer.WriteEndElement();writer.WriteEndElement();//再次释放writer.Flush();Console.WriteLine(此时内存使用量为:{2}KB,该MemoryStream的已经使用的容量为{0}byte,默认容量为{1}byte,Math.Round((double)ms.Length, 4), ms.Capacity, GC.GetTotalMemory(false)/1024);//建立一个FileStream 文件创建目的地是d:\test.xmlFileStream fs new FileStream(d:\test.xml,FileMode.OpenOrCreate);using (fs){//将内存流注入FileStreamms.WriteTo(fs);if(ms.CanWrite)//释放缓冲区fs.Flush();}}}}       输出结果 简单示例自定义一个处理图片的HttpHandler  有时项目里我们必须将图片进行一定的操作例如水印下载等为了方便和管理我们可以自定义一个HttpHander 来负责这些工作 后台 public class ImageHandler : IHttpHandler{#region IHttpHandler Memberspublic bool IsReusable{get { return true; }}/// summary/// 实现IHTTPHandler后必须实现的方法/// /summary/// param namecontextHttpContext上下文/parampublic void ProcessRequest(HttpContext context){context.Response.Clear();//得到图片名var imageName context.Request[ImageName] null ? 逆时针的风: context.Request[ImageName].ToString();//得到图片ID,这里只是演示实际项目中不是这么做的var id context.Request[Id] null ? 01: context.Request[Id].ToString();//得到图片地址var stringFilePath context.Server.MapPath(string.Format(~/Image/{0}{1}.jpg, imageName, id));//声明一个FileStream用来将图片暂时放入流中FileStream stream new FileStream(stringFilePath, FileMode.Open);using (stream){//透过GetImageFromStream方法将图片放入byte数组中byte[] imageBytes this.GetImageFromStream(stream,context);//上下文确定写到客户短时的文件类型context.Response.ContentType image/jpeg;//上下文将imageBytes中的数据写到前段context.Response.BinaryWrite(imageBytes);stream.Close();}}/// summary/// 将流中的图片信息放入byte数组后返回该数组/// /summary/// param namestream文件流/param/// param namecontext上下文/param/// returns/returnsprivate byte[] GetImageFromStream(FileStream stream, HttpContext context){//通过stream得到ImageImage image Image.FromStream(stream);//加上水印image SetWaterImage(image, context);//得到一个ms对象MemoryStream ms new MemoryStream();using (ms){//将图片保存至内存流image.Save(ms, ImageFormat.Jpeg);byte[] imageBytes new byte[ms.Length];ms.Position 0;//通过内存流读取到imageBytesms.Read(imageBytes, 0, imageBytes.Length);ms.Close();//返回imageBytesreturn imageBytes;}}/// summary/// 为图片加上水印这个方法不用在意只是演示所以没加透明度/// 下次再加上吧/// /summary/// param nameimage需要加水印的图片/param/// param namecontext上下文/param/// returns/returnsprivate Image SetWaterImage(Image image,HttpContext context) {Graphics graphics Graphics.FromImage(image);Image waterImage Image.FromFile(context.Server.MapPath(~/Image/逆时针的风01.jpg));//在大图右下角画上水印图就行graphics.DrawImage(waterImage,new Point { X image.Size.Width - waterImage.Size.Width,Y image.Size.Height - waterImage.Size.Height });return image;}#endregion} 别忘了还要在Web.Config中进行配置别忘记verb和path属性否则会报错 httpHandlersadd typeImageHandler.ImageHandler,ImageHandler verb* pathImageHandler.apsx//httpHandlers 这样前台便能使用了 asp:Content IDBodyContent runatserver ContentPlaceHolderIDMainContenth2About/h2pPut content here.asp:Image runatserver ImageUrlImageHandler.apsx?ImageName逆时针的风Id02 //p /asp:Content 输出结果    本章总结   本章主要介绍了MemoryStream 的一些概念异常结构包括如何使用如何解决一些异常等感谢大家一直支持和鼓励文中如出现错误还请大家海涵深夜写文不容易   还请大家多多关注下篇会介绍BufferedStream尽请期待  转载于:https://www.cnblogs.com/Zsundy/p/9325339.html
http://www.pierceye.com/news/738807/

相关文章:

  • 武城网站建设费用网页设计试题及答案
  • 郑州外贸网站建设公司搜索引擎排名的三大指标
  • 温州专业微网站制作电台 主题 wordpress
  • wordpress做网站过程阳江网上车管所
  • 网站抓取qq上海自贸区注册公司流程
  • 深圳网站设计推荐刻烟台制作网站有哪些
  • 网站注册系统源码卢松松博客源码 wordpress博客模板
  • 网站开发进阶实训报告廊坊安次区网站建设公司
  • jquery插件网站推荐打开网站自动跳转代码
  • 佛山顺德容桂网站制作写作平台
  • 网站源码下载pdf文件品质好房
  • 山网站建设长沙网站开发湖南微联讯点不错
  • 网站建设的方案模板邢台123今天的招聘信息
  • 一个网站做app网站如何做收款二维码
  • 济南seo网站优化网站开发源代码 百度文库
  • 东西湖区建设局网站制作网站需要钱吗
  • 自己买服务器能在wordpress建网站欧美色影网站
  • 网站支付页面设计金华企业网站建设公司
  • wordpress评论模块临沂seo网站管理
  • 四川法制建设网站产品推广步骤
  • 服务器 网站建设比较容易做流量的网站
  • 网站建设基础实训报告天津滨海新区地图全图
  • 兰西网站建设深圳58同城招聘网
  • 兰州网站建设程序烟台赶集网网站建设
  • 自己建立网站后怎么做淘客wordpress需要npv
  • 简单网站建设推荐wordpress主题ashley
  • 单页网站开发实例下载电商营销渠道有哪些
  • 沈阳科技网站首页东营市做网站
  • 网站移动端开发公司客户评价网站建设
  • 有没有做问卷还能赚钱的网站鲜花网站数据库建设