在处理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 修饰符为 ...
随机推荐
- centOs下的php+mysql+apache+ftp配置
在安装服务器时做了相应的笔记,这个方法是亲身经验成功的,随着版本的不断更新,也许会有一些地方不同,但是基本原理都是一样的. 1.安装CentOS 6 ,可以选择最小安装,也可以安装桌面 2.升级系统 ...
- oracle中的初始化参数文件
oracle初始化参数文件管理 oracle实例是指运行状态下的oracle软件,是由内存结构跟一些进程结构组成的,主要实现数据库的访问跟控制功能,是oracle的核心. 初始化参数文件是oracle ...
- 菜鸟的jQuery源码学习笔记(三)
each: function(callback, args) { return jQuery.each(this, callback, args); }, each:这个调用了jQuery.each方 ...
- Android之 compileSdkVersion, minSdkVersion, and targetSdkVersion
在一年之中,也有可能只是几个月后,你会发布你的Android应用程序.但是这中间有可能会发布新的版本的Android系统,比如:6.0+. 你肯定希望你的应用可以向前兼容,当用户升级到新的Androi ...
- jquery EsayUi 里一个小弹框
网站后台大多的数据展示就都用和此插件有着密切的关系: 来用一下这个小弹框吧: 一个Html里面的代码 <link rel='stylesheet' type='text/css' href='c ...
- SQL Server 从数据库快照还原数据库
语法: restore database db_name from database_snapshot = 'db_snapshot_name'; ------------------------- ...
- Struts2的Stack Context和ValueStack
1.提到Struts2的传值功能时,经常会见到Stack Context和ValueStack等概念,那么它们到底是什么,有什么作用呢. ValueStack(值栈):Struts2将OGNL上下文设 ...
- jQuery学习-事件之绑定事件(七)
今天来说说事件中的handlers方法中的一个片段 1 matches[ sel ] = handleObj.needsContext ? 2 jQuery( sel, this ).in ...
- VS 2012 插件卸载(删除自己安装的插件)
给VS 装了一个插件,装完之后感觉别扭,所以想卸载,[工具]--> [扩展和更新]-->[找到想要卸载的插件点击一下就会出现禁用或卸载]
- Android客户端与服务器交互中的token
学习Token Token是什么? Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Tok ...