C# 温故而知新:Stream篇(五)下
时间:2022-05-07
本文章向大家介绍C# 温故而知新:Stream篇(五)下,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
对于重写的方法这里不再重复说明,大家可以参考我写的第一篇
以下是memoryStream独有的方法
virtual byte[] GetBuffer()
这个方法使用时需要小心,因为这个方法返回无符号字节数组,也就是说,即使我只输入几个字符例如”HellowWorld”我们只希望返回11个数据就行,
可是这个方法会把整个缓冲区的数据,包括那些已经分配但是实际上没有用到的字节数据都返回出来,如果想启用这个方法那必须使用上面最后一个构
造函数,将publiclyVisible属性设置成true就行,这也是上面那个构造函数的作用所在
virtual void WriteTo(Stream stream)
这个方法的目的其实在本文开始时讨论性能问题时已经指出,memoryStream常用起中间流的作用,
所以读写在处理完后将内存流写入其他流中
简单示例 XmlWriter中使用MemoryStream
/// <summary>
/// 演示在xmlWriter中使用MemoryStream
/// </summary>
public static void UseMemoryStreamInXMLWriter()
{
MemoryStream ms = new MemoryStream();
using (ms)
{
//定义一个XMLWriter
using (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.xml
FileStream fs = new FileStream(@"d:test.xml",FileMode.OpenOrCreate);
using (fs)
{
//将内存流注入FileStream
ms.WriteTo(fs);
if(ms.CanWrite)
//释放缓冲区
fs.Flush();
}
}
}
}
输出结果:
简单示例:自定义一个处理图片的HttpHandler
有时项目里我们必须将图片进行一定的操作,例如水印,下载等,为了方便和管理我们可以自定义一个HttpHander 来负责这些工作
后台:
public class ImageHandler : IHttpHandler
{
#region IHttpHandler Members
public bool IsReusable
{
get { return true; }
}
/// <summary>
/// 实现IHTTPHandler后必须实现的方法
/// </summary>
/// <param name="context">HttpContext上下文</param>
public 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 name="stream">文件流</param>
/// <param name="context">上下文</param>
/// <returns></returns>
private byte[] GetImageFromStream(FileStream stream, HttpContext context)
{
//通过stream得到Image
Image 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;
//通过内存流读取到imageBytes
ms.Read(imageBytes, 0, imageBytes.Length);
ms.Close();
//返回imageBytes
return imageBytes;
}
}
/// <summary>
/// 为图片加上水印,这个方法不用在意,只是演示,所以没加透明度
/// 下次再加上吧
/// </summary>
/// <param name="image">需要加水印的图片</param>
/// <param name="context">上下文</param>
/// <returns></returns>
private 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属性,否则会报错
<httpHandlers>
<add type="ImageHandler.ImageHandler,ImageHandler" verb="*" path="ImageHandler.apsx"/>
</httpHandlers>
这样前台便能使用了
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<h2>
About </h2>
<p>
Put content here. <asp:Image runat="server" ImageUrl="ImageHandler.apsx?ImageName=逆时针的风&Id=02" />
</p></asp:Content>
输出结果
本章总结
本章主要介绍了MemoryStream 的一些概念,异常,结构,包括如何使用,如何解决一些异常等
- vue.js使用props在父子组件之间传参
- JS中使用正则表达式替换对象里的大小写
- JS中const、var 和let的区别
- 动态计算rem的js代码
- 阻止浏览器冒泡事件,兼容firefox和ie
- JS使用循环按指定倍数分割数组组成新的数组的方法
- HttpServletRequest.getParameter()出现乱码现象解决方案
- 海量数据迁移之外部表加载(100天)
- Vue.js实现一个SPA登录页面的过程
- vue实现侧边栏手风琴效果
- 关于vue的使用计算属性VS使用计算方法的问题
- 如何在vue中使用sass
- vue -- v-cloak解决刷新或者加载出现闪烁(显示变量)
- jquery实现上下滑动选择
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 京东技术主导:全新架构的分布式事务Hmily 2.1.1发布
- iOS音视频接入-TRTC接入前期key、秘钥等准备
- 你一定不知道的 Linux 使用技巧
- 当 Python 爬虫搭配起 Bilibili 唧唧,奇怪的生产力出现了
- 一个简单的小技巧,监控网页所有动态标签创建的调用处
- SAP Spartacus storefrontapp index.html的design time和runtime
- OS开发爱好者福利来了:树莓派上编译C语言,顺便掌握一波硬件知识
- 一个简单易用的图标字体库和CSS框架fontawesome
- OLAP 数据平台 Druid 第一步,编写 Spec 配置
- 搭建 Kubernetes 集群 Dashboard 2.0+ 可视化插件
- Kubernetes 集群基本概念
- 未能幸免!安全容器也存在逃逸风险
- vue中v-for图片src路径错误
- 读书笔记 dotnet 什么时候进行垃圾回收
- Windows系统下ROS1或ROS2获取RTSP视频等功能包