在处理Stream型态时常会使用到Stream.Write这个方法,每次都会有种疑问就是,大多数的处理都是要将Buffer整个写入,為何偏偏每次都要将索引带0,长度带為Buffer的大小呢?另外在处理Stream时,若要显示其处理进度,是否能有更為简单的方法?这边将我為了解决这些问题所写的扩充方法整裡如下:
02 |
using System.Reflection; |
03 |
using System.ComponentModel; |
07 |
public static class StreamExtension |
09 |
public static void Write(this Stream targetStream, byte[] buffer) |
11 |
if (!targetStream.CanWrite) |
12 |
throw new ArgumentException("targetStream", "Unwritable stream"); |
14 |
targetStream.Write(buffer, 0, buffer.Length); |
17 |
public static void Write(this Stream targetStream, Stream sourceStream) |
19 |
if (!targetStream.CanWrite) |
20 |
throw new ArgumentException("targetStream", "Unwritable stream"); |
22 |
if (sourceStream == null) |
23 |
throw new ArgumentNullException("sourceStream"); |
25 |
if (!sourceStream.CanRead) |
26 |
throw new ArgumentException("sourceStream", "Unreadable stream"); |
28 |
targetStream.Write(sourceStream, 1024, null); |
31 |
public static void Write(this Stream targetStream, Stream sourceStream, int bufferSize, Action<object, System.ComponentModel.ProgressChangedEventArgs> progressChangedCallBack) |
33 |
if (sourceStream == null) |
34 |
throw new ArgumentNullException("sourceStream"); |
36 |
if (!sourceStream.CanRead) |
37 |
throw new ArgumentException("sourceStream", "Unreadable stream"); |
39 |
if (!targetStream.CanWrite) |
40 |
throw new ArgumentException("targetStream", "Unwritable stream"); |
42 |
if (bufferSize < 1024) |
43 |
throw new ArgumentOutOfRangeException("bufferSize", "Must bigger than 1024"); |
45 |
byte[] buffer = new byte[bufferSize]; |
48 |
int readByteCount = 0; |
51 |
while ((readByteCount = sourceStream.Read(buffer, 0, bufferSize)) > 0) |
53 |
targetStream.Write(buffer, 0, readByteCount); |
55 |
if (progressChangedCallBack != null) |
57 |
offset += readByteCount; |
59 |
var currentPercent = (int)(((double)offset) / sourceStream.Length * 100); |
60 |
if (currentPercent == percent) |
63 |
percent = currentPercent; |
64 |
progressChangedCallBack(targetStream, new System.ComponentModel.ProgressChangedEventArgs(percent, null)); |
使用上Write方法會多三個多載版本,一個是將buffer整個寫入、一個是將stream的內容整個讀出並寫入、一個則是用來寫入整個stream內容,並可帶入處理的Buffer大小,與處理進度回報的Callback,用以處理進度的顯示。
1 |
targetStream.Write(buffer); |
2 |
targetStream.Write(sourceStream); |
3 |
targetStream.Write(sourceStream, 1024, (sender, e) => { Console.WriteLine(e.ProgressPercentage.ToString ()); }); |
這邊針對進度處理的擴充方法示範個較為詳細的範例,這邊我會讀取C槽下的test.data檔案,檔案大小為5MB多,開啟後將其寫入c槽下的test_copy.data。處理的buffer大小為1024,每當在處理時偵測到進度改變時會顯示出當前處理的進度比例。
02 |
using System.Collections.Generic; |
07 |
namespace ConsoleApplication11 |
11 |
static void Main(string[] args) |
13 |
using (FileStream targetStream = File .Create (@"c:\test_copy.dat")) |
15 |
using (FileStream sourceStream= File.Open (@"c:\test.dat", FileMode.Open)) |
17 |
targetStream.Write(sourceStream, 1024, (sender, e) => { Console.WriteLine(e.ProgressPercentage.ToString()); }); |
運行結果如下:

- [C#] Extension Method 扩展方法
当我们引用第三方的DLL.或者Visual Studio自己的库的时候,或许会发现这样的一个情况,如果这个类型有一个XX的方法就好了.这时候我们可以用到扩展方法,是我们的代码更加灵活和高效. 这里我举 ...
- 动态linq表达式新方法,Dynamic LINQ Extension Method
Remember those old posts on Dynamic LINQ? You are probably aware that Microsoft has made its impleme ...
- Extension Method[下篇]
四.Extension Method的本质 通过上面一节的介绍,我们知道了在C#中如何去定义一个Extension Method:它是定义在一个Static class中的.第一个Parameter标 ...
- Extension Method[上篇]
在C#3.0中,引入了一些列新的特性,比如: Implicitly typed local variable, Extension method,Lambda expression, Object i ...
- C# Note21: 扩展方法(Extension Method)及其应用
前言 今天在开会时提到的一个概念,入职3个多月多注重在项目中使用C#的编程知识,一直没有很认真地过一遍C#的全部语法,当我们新人被问及是否了解Extension Method时,一时之间竟不能很通俗准 ...
- [译文]c#扩展方法(Extension Method In C#)
原文链接: https://www.codeproject.com/Tips/709310/Extension-Method-In-Csharp 介绍 扩展方法是C# 3.0引入的新特性.扩展方法使你 ...
- C#编译问题'System.Collections.Generic.IEnumerable' does not contain a definition for 'Where' and no extension method 'Where' accepting a first argument
'System.Collections.Generic.IEnumerable<string>' does not contain a definiti ...
- Swift protocol extension method is called instead of method implemented in subclass
Swift protocol extension method is called instead of method implemented in subclass protocol MyProto ...
- Extension method for type
扩展其实真的很简单 msdn是这样规定扩展方法的:"扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的. 它们的第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为 ...
随机推荐
- Java多线程并发编程之原子变量与非阻塞同步机制
1.非阻塞算法 非阻塞算法属于并发算法,它们可以安全地派生它们的线程,不通过锁定派生,而是通过低级的原子性的硬件原生形式 -- 例如比较和交换.非阻塞算法的设计与实现极为困难,但是它们能够提供更好的吞 ...
- 开发移动端web应用, 使用手机自带键盘的搜索按钮
很多时候在移动端的web页面中, 需要使用搜索功能, 然而页面中并没有太多的空间来放置一个像pc端上那样的搜索按钮, 这时候就需要借用手机输入法自带的搜索按钮来实现点击搜索 虽然不是什么大的功能, 但 ...
- SEO高手在扯蛋?
真正的高手SEO你在扯蛋吗?当大家都很会扯的时候,高手扯得肯定比你疼,不是他们 蛋比较敏感,而是他们的确更用力. 当你说我是SEO时,高手肯定说现在我在做的是SEM. 当你说我是SEM时,高手肯定在说 ...
- linux GUI程序开发
1,C++ OOP中 class与C 面向过程开发中struct非常相似
- BZOJ 3237([Ahoi2013]连通图-cdq图重构-连通性缩点)
3237: [Ahoi2013]连通图 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 106 Solved: 31 [ Submit][ St ...
- Qemu之Network Device全虚拟方案二:虚拟网卡的创建
上文针对Qemu在前端网络流路径的建立方面做了具体的描写叙述.数据包从Host的物理网卡经过Host Linux内核中的Bridge, 经过Tap设备到达了Qemu的用户态空间.而Qemu是怎样把数据 ...
- VS2010在C盘下生成的.iTrace文件解决办法 ,c盘偷偷的减少,心很烦啊,找了半天才知道是这个问题
用Visual Studio 2010后发现我的c盘变得越来越小了,刚开始通过优化工具清理c盘,但是无论怎么做都不能将c的内存有效提升,之后一个一个目录的查找之后才知道有个文件夹C:\ProgramD ...
- 《think in python》学习-4
think in python -4 接口设计: 本章引入了一个实例 来讲解接口方面的知识. 准备工作: 下载swampy模块,从地址下载,并安装,安装信息可以从网页上查看. swampy模块 提供各 ...
- MSSQL查询连接数
SELECT * FROM [Master].[dbo].[SYSPROCESSES] WHERE [DBID] IN ( SELECT [DBID] FROM [Master].[dbo].[SYS ...
- sqlserver查询某一字段重复超5次的所有记录
用的sqlserver2008 r2. SELECT * FROM t_class WHERE id IN (SELECT id FROM (SELECT ROW_NUMBER() OVER ( ...