在.NET中使用管道将输出流转换为输入流
最近在写一段代码,将本地文件压缩加密后发送到服务器,发送到服务器的类用一个输入流作为参数获取要上传的数据,而压缩类和加密类都是输出流。
如何将输出流转换为输入流,最直观的方法是缓存输出流的全部内容到内存或文件中,但是当数据变大的时候,这两种方法显然都不太合适。
通过使用管道,可以将一个输出流转换为输入流。管道是一个操作系统功能,由一个循环缓存区构成,用于进程间通信,将一个进程的输出做为另一个进程的输入,Linux命令行脚本大量的用到管道通信,Windows同样也支持管道。.net对管道有封装的类,使用管道,在两个线程间通信,将一个进程的输出传递到另一个进程作为输入,.net中管道类继承自Stream类,可以将输出流无缝衔接到输入流。
参照AnonymousPipeClientStream类和AnonymousPipeServerStream类的文档,将进程间通信改为线程间通信,就实现了在一个应用程序中将输出类转换为输入类的功能,代码如下:
[TestMethod]
public void OutputStream2InputStreamUsingPipe()
{
int iStreamSize = * ; var t = new Thread((data) =>
{
using (var pipe = new AnonymousPipeClientStream(
PipeDirection.Out, (string)data))
{
for (var i = ; i < iStreamSize; i++)
pipe.WriteByte((byte)'A');
}
}); using (var ms = new MemoryStream())
{
using (var pipe = new AnonymousPipeServerStream(
PipeDirection.In, HandleInheritability.Inheritable))
{
t.Start(pipe.GetClientHandleAsString());
var buffer = new byte[ * ];
int len;
while ((len = pipe.Read(buffer, , buffer.Length)) > )
{
Thread.Sleep();
ms.Write(buffer, , len);
}
}
t.Join();
Assert.AreEqual(iStreamSize, ms.Length);
}
}
在上述代码中在一个新建线程中向管道的一端写入数据,在主线程中从管道的另一端读取数据。如果写入前和读取后都需要对数据进行处理的话,若能将数据处理工作分配到两个线程上,既解决了流转换的问题,而且如果数据处理工作占用CPU很多的话双线程带来的效率提升不仅会抵消掉使用管道带来的开销,还能进一步提升整体效率,一举两得。
代码中Thread.Sleep(100)明确地使管道的写入和读取不同步,以验证管道的功能:当读取线程进入Sleep状态时,管道缓冲区被写满(windows和linux下缓存区可能都是一个内存页4K),写入操作被阻塞。
在.NET中使用管道将输出流转换为输入流的更多相关文章
- Angular4中常用管道(转载)
Angular4中常用管道 通常我们需要使用管道实现对数据的格式化,Angular4中的管道和之前有了一些变化,下面说一些常用的管道. 一.大小写转换管道 uppercase将字符串转换为大写 low ...
- Angular4中常用管道
通常我们需要使用管道实现对数据的格式化,Angular4中的管道和之前有了一些变化,下面说一些常用的管道. 一.大小写转换管道 uppercase将字符串转换为大写 lowercase将字符串转换为小 ...
- java中PipedStream管道流通信详细使用(详解)
多线程使用PipedStream 通讯 Java 提供了四个相关的管道流,我们可以使用其在多线程进行数据传递,其分别是 类名 作用 备注 PipedInputStream 字节管道输入流 字节流 Pi ...
- 详解Java中的IO输入输出流!
目录 本片要点 基本分类 发展史 文件字符流 输出的基本结构 流中的异常处理 异常处理新方式 读取的基本结构 运用输入与输出完成复制效果 文件字节流 缓冲流 字符缓冲流 装饰设计模式 转换流(适配器) ...
- 如何在eclipse jee中创建Maven project并且转换为Dynamic web project
如何在eclipse jee中创建Maven project并且转换为Dynamic web project 注意:该文档只针对以下eclipse版本,如图 为了方便,我将我本地的压缩包放在了微云网盘 ...
- 将html中的br换行符转换为文本输入中的换行符(转)
PHP中的有个非常好的函数:nl2br(),将文本框中的换行转换为HTML页面的<br />,但是如何实现将html中的<br />换行符转换为文本框中的换行符呢?下面这几个方 ...
- Core 1.0中的管道-中间件模式
ASP.NET Core 1.0中的管道-中间件模式 SP.NET Core 1.0借鉴了Katana项目的管道设计(Pipeline).日志记录.用户认证.MVC等模块都以中间件(Middlewar ...
- .NET客户端实现Redis中的管道(PipeLine)与事物(Transactions)
序言 Redis中的管道(PipeLine)特性:简述一下就是,Redis如何从客户端一次发送多个命令,服务端到客户端如何一次性响应多个命令. Redis使用的是客户端-服务器模型和请求/响应协议的T ...
- SQL零星技术点:SQL中转换money类型数值转换为字符串问题
--SQL中转换money类型数值转换为字符串问题,直接转换就转为两位了,所以需要做一下处理.具体请看下述sql实例. 1 create table #test(price money) insert ...
随机推荐
- 安装storm的一些很乱的笔记
下面是自己安装和测试storm的一些笔记,比较乱,后续有时间在整理一篇. storm jar all-my-code.jar com.storm.MyTopology arg1 arg2这个命令会运行 ...
- POJ 1743 Musical Theme ——后缀数组
[题目分析] 其实找最长的不重叠字串是很容易的,后缀数组+二分可以在nlogn的时间内解决. 但是转调是个棘手的事情. 其实只需要o(* ̄▽ ̄*)ブ差分就可以了. 背板题. [代码] #include ...
- LINUX 文件权限详解
ls -l // 查看文件的权限 等价于 ll 文件的权限信息查看 -rw-rw-r-- 1 ceshi ceshi 891 Aug 8 17:28 server drwxrwxr-x 10 cesh ...
- selenium获取Cookie操作
直接贴代码: Set cookies = dr.manage().getCookies(); for (Cookie cookie : cookies) { System.out.println(&q ...
- Java Web 项目目录规范
一.项目结构 这里和其他项目区别不大,我将模板抽离出来,更容易分析和理解: 解释一下:js主要包括extends(引入第三方的js).module(项目模块自己的js).lib(引用包,这里也可以继续 ...
- 关于WM_GETTEXT的应用
HWND hw = ::FindWindow(NULL,"Form1"); HWND hw2 = ::FindWindowEx(hw,NULL,NULL,NULL); int le ...
- compass typography 排版 常用排版方法[Sass和compass学习笔记]
Bullets 用来定义ul li 相关的样式 no-bullet 关闭 li的默认样式 那个小圆点 no-bullets 作用域ul 调用no-bullet 函数 不过用了reset 后 默认没有 ...
- VIM 解决中文乱码
$ vim ~/.vimrc 加入以下内容 set fileencodings=utf-8,ucs-bom,gb18030,gbk,gb2312,cp936 set termencoding=utf- ...
- 基于synchronized 或 ReadWriteLock实现 简单缓存机制
package cn.xxx.xxx; import java.util.HashMap; import java.util.Map; import java.util.concurrent.lock ...
- ceil 模块
# 有时需要得到一个最小的整数,而这个数只能比自己大或相等,不能小于自己 #如: 2.1 我们需要得到的最小整数为3,即使后一位只有很小的一部分,一般用于分页 from math import cei ...