在处理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 修饰符为 ...
随机推荐
- javascript的调试
1. 关于javascript的调试,最好将浏览器的脚本通知打开. 2. 最好设置为每次访问页面时检查.
- 当tomcat有两个链接数据库的应用同时运行可能冲突
-Xms512M -Xmx1024M -XX:MaxPermSize=256M
- IPTV小窗口播放视频 页面焦点无法移动的解决方法
在IPTV高清页面中,小窗口播放视频时,在某些机顶盒上(如高清中兴.高清大亚4904)会出现焦点无法移动现象,即按键无响应.被这个bug困扰了很久,虽然我知道解决方法,但只知其然,不知其所以然.今天做 ...
- bootstrap 简易模版
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...
- Canvas、Paint、的简单使用及辅助类(Path、Shader、简介)
1.Canvas类 作用:1.绘制各种图形.图片.字等.2.提供各种方法进行坐标变换(rotate.scale.skew.translate) 获取Canvas:一般是子类继承View并重写onDra ...
- PHP面试题之算法解析
面试中经常被问到会什么算法,这里整合一些常见的算法及它们的实现原理.下面的例子都是经过测试可用的,如果有什么问题请告知!! 本人小白,如果有更好的实现方式,敬请赐教,感激不尽!!!! 冒泡排序,快速排 ...
- Java 中使用Jackson反序列化
Build.gradle: compile group: 'org.codehaus.jackson', name: 'jackson-mapper-lgpl', version: '1.9.13' ...
- Android05-UI02布局,自定义控件,ListView
1.布局 布局的内部除了放置控件外,也可以放置布局,通过多层布局的嵌套,我们就能够完成一些 比较复杂的界面实现 ¨四种基本布局 LinearLayout RelativeLayout FrameLay ...
- php set env
SYSTEM WARNING: 'date_default_timezone_get(): It is not safe to rely on the system's timezone settin ...
- 公司需求知识自学- Hashtable简单应用
定义表 Hashtable tblNames = new Hashtable(); 添加key,value键值对 tblNames.Add("A","a"); ...