在处理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 修饰符为 ...
随机推荐
- ASP.NET DataList绑定数据并实现分页
显示当前页码Label属性 值ID NowPageNumberLabtext 1 ×××××××××××××××××××××显示总页码Label属性 值ID BackPageNumberLabt ...
- JAVA 8 新特性和改进
Java 8的所有新特性及改进包括(JEP全称为JDK Enhancement Proposal,JDK改进建议): 语言改进: JEP 126:Lambda表达式 & 虚拟扩展方法 JEP ...
- 写给初学者css优先级问题
首先需要搞清楚几个基本概念 1.内嵌样式: 写在元素标签内的例如:<div style="background-color:red"> </div> 2.内 ...
- TensorFlow 深度学习笔记 Logistic Classification
Logistic Classification Github工程地址:https://github.com/ahangchen/GDLnotes 欢迎star,有问题可以到Issue区讨论 官方教程地 ...
- SQL Server 查看指定表上的索引
解决方案: sys.indexs; ---------------------------------------------------------------------------------- ...
- aix运维
AIX操作系统中有很多程序,为了进行程序版本控制,每一个程序集都有自己的版本号.版本号是由小数点分隔的四位数字,例如5.3.0.9其含义是:操作系统版本号(version).发行版本号(release ...
- mysql数据库学习(二)--表操作
一.表操作 以下内容都是自己学习的时候看过的一些知识,作为笔记记录一下吧,大部分都是所看文章的内容. 1.创建表 前面的基础篇笔记是相当于搭建了一个方便管理的文件夹树根,下面要学习的是一些关于表的知识 ...
- AngularJs(三) deployd 服务的使用
使用服务建立数据 在AngularJS(二)中,我搭建好了deployd服务,现在启动服务,创建正在的数据(开始是使用模拟数据),使用cmd命令 一.开启Mongodb数据. 贴图: 二:测试是否正常 ...
- html标签总结。
接触了一段时间的html和css,发现了其中的乐趣.在写代码时一定要仔细,很有可能一个细微的错误便会导致页面的错误 总结了一下html标签. <html></html> 创建一 ...
- JAVA 从GC日志分析堆内存 第七节
JAVA 从GC日志分析堆内存 第七节 在上一章中,我们只设置了整个堆的内存大小.但是我们知道,堆又分为了新生代,年老代.他们之间的内存怎么分配呢?新生代又分为Eden和Survivor,他们的比 ...