在处理Stream型态时常会使用到Stream.Write这个方法,每次都会有种疑问就是,大多数的处理都是要将Buffer整个写入,為何偏偏每次都要将索引带0,长度带為Buffer的大小呢?另外在处理Stream时,若要显示其处理进度,是否能有更為简单的方法?这边将我為了解决这些问题所写的扩充方法整裡如下:

using System;
02 using System.Reflection;
03 using System.ComponentModel;
04 using System.Linq;
05 using System.IO;
06  
07 public static class StreamExtension
08 {
09     public static void Write(this Stream targetStream, byte[] buffer)
10     {
11         if (!targetStream.CanWrite)
12             throw new ArgumentException("targetStream", "Unwritable stream");
13  
14         targetStream.Write(buffer, 0, buffer.Length);
15     }
16  
17     public static void Write(this Stream targetStream, Stream sourceStream)
18     {
19         if (!targetStream.CanWrite)
20             throw new ArgumentException("targetStream", "Unwritable stream");
21  
22         if (sourceStream == null)
23             throw new ArgumentNullException("sourceStream");
24  
25         if (!sourceStream.CanRead)
26             throw new ArgumentException("sourceStream", "Unreadable stream");
27  
28         targetStream.Write(sourceStream, 1024, null);
29     }
30  
31     public static void Write(this Stream targetStream, Stream sourceStream, int bufferSize, Action<object, System.ComponentModel.ProgressChangedEventArgs> progressChangedCallBack)
32     {
33         if (sourceStream == null)
34             throw new ArgumentNullException("sourceStream");
35  
36         if (!sourceStream.CanRead)
37             throw new ArgumentException("sourceStream", "Unreadable stream");
38  
39         if (!targetStream.CanWrite)
40             throw new ArgumentException("targetStream", "Unwritable stream");
41  
42         if (bufferSize < 1024)
43             throw new ArgumentOutOfRangeException("bufferSize", "Must bigger than 1024");
44  
45         byte[] buffer = new byte[bufferSize];
46  
47         int offset = 0;
48         int readByteCount = 0;
49         int percent = 0;
50  
51         while ((readByteCount = sourceStream.Read(buffer, 0, bufferSize)) > 0)
52         {
53             targetStream.Write(buffer, 0, readByteCount);
54  
55             if (progressChangedCallBack != null)
56             {
57                 offset += readByteCount;
58  
59                 var currentPercent = (int)(((double)offset) / sourceStream.Length * 100);
60                 if (currentPercent == percent)
61                     continue;
62  
63                 percent = currentPercent;
64                 progressChangedCallBack(targetStream, new System.ComponentModel.ProgressChangedEventArgs(percent, null));
65             }
66         }
67     }
68 }

使用上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,每當在處理時偵測到進度改變時會顯示出當前處理的進度比例。

01 using System;
02 using System.Collections.Generic;
03 using System.Linq;
04 using System.Text;
05 using System.IO;
06  
07 namespace ConsoleApplication11
08 {
09     class Program
10     {
11         static void Main(string[] args)
12         {           
13                 using (FileStream targetStream = File .Create (@"c:\test_copy.dat"))
14                 {
15                     using (FileStream sourceStream= File.Open (@"c:\test.dat", FileMode.Open))
16                     {
17                         targetStream.Write(sourceStream, 1024, (sender, e) => { Console.WriteLine(e.ProgressPercentage.ToString()); });
18                     }
19                 }
20         }
21     }
22 }

運行結果如下:

[C#]Stream.Write Extension Method的更多相关文章

  1. [C#] Extension Method 扩展方法

    当我们引用第三方的DLL.或者Visual Studio自己的库的时候,或许会发现这样的一个情况,如果这个类型有一个XX的方法就好了.这时候我们可以用到扩展方法,是我们的代码更加灵活和高效. 这里我举 ...

  2. 动态linq表达式新方法,Dynamic LINQ Extension Method

    Remember those old posts on Dynamic LINQ? You are probably aware that Microsoft has made its impleme ...

  3. Extension Method[下篇]

    四.Extension Method的本质 通过上面一节的介绍,我们知道了在C#中如何去定义一个Extension Method:它是定义在一个Static class中的.第一个Parameter标 ...

  4. Extension Method[上篇]

    在C#3.0中,引入了一些列新的特性,比如: Implicitly typed local variable, Extension method,Lambda expression, Object i ...

  5. C# Note21: 扩展方法(Extension Method)及其应用

    前言 今天在开会时提到的一个概念,入职3个多月多注重在项目中使用C#的编程知识,一直没有很认真地过一遍C#的全部语法,当我们新人被问及是否了解Extension Method时,一时之间竟不能很通俗准 ...

  6. [译文]c#扩展方法(Extension Method In C#)

    原文链接: https://www.codeproject.com/Tips/709310/Extension-Method-In-Csharp 介绍 扩展方法是C# 3.0引入的新特性.扩展方法使你 ...

  7. C#编译问题'System.Collections.Generic.IEnumerable' does not contain a definition for 'Where' and no extension method 'Where' accepting a first argument

    &apos;System.Collections.Generic.IEnumerable<string>&apos; does not contain a definiti ...

  8. 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 ...

  9. Extension method for type

    扩展其实真的很简单 msdn是这样规定扩展方法的:"扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的. 它们的第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为 ...

随机推荐

  1. css3之3D翻牌效果

      最近一直在学css3,发现他真的是越来越牛逼.现在的css3已经不在是以前的css了,它能做出的功能效果是我们没法想象的了.它可以实现flash,可以制作一些js能做出来的效果,还可以写出ps做出 ...

  2. Android Webview与Html5交互

    转:http://fangjie.info/?p=417#more-417   一.WebView.setWebViewClient(new MyWebViewClient()); 1.public ...

  3. HTML5之Viewport详解

    做移动Web开发也有一年多的时间了,虽然手机上浏览器对于PC上来说很友好了,但是手机各种设备的显示尺寸分辨率大小不一也要花大心思兼容它们. 关于HTML5中Viewport的文章Google,百度一搜 ...

  4. JavaScript基本概念(变量和数据类型)

    1. 变量 在局部作用域中省略var操作符可以定义全局变量,但是这么做会导致该变量难以维护,且在严格模式下会导致抛出ReferenceError错误. 2. 数据类型(js共用6种数据类型,分别是 U ...

  5. jquery的冒泡和默认行为

    如果在页面中重叠了多个元素,并且重叠的这些元素都绑定了同一个事件,那么就会出现冒泡问题. //HTML 页面 <div style="width:200px;height:200px; ...

  6. C语言中内存分配 (转)

    在任何程序设计环境及语言中,内存管理都十分重要.在目前的计算机系统或嵌入式系统中,内存资源仍然是有限的.因此在程序设计中,有效地管理内存资源是程序员首先考虑的问题. 第1节主要介绍内存管理基本概念,重 ...

  7. CentOS DNS resolv重启无效的解决方法

    分类: LINUX 直接修改/etc/resolv.conf不行.必须要在/etc/sysconfig/network-scripts/ifcfg-eth0里面最后 加上dns的设置.要不然,重启后, ...

  8. MATLAB中文论坛帖子整理(GUI)

    MATLAB中文论坛帖子整理(GUI) 目   录  1.GUI新手之——教你读懂GUI的M文件... 10 2.GUI程序中改变current directory引起的问题... 15 3.GUI中 ...

  9. android 百度地图定位功能实现

    历经几天时间,终于把定位功能给实现了,可谓是费劲千辛万苦啊,有定位知识还有图层知识,在这里我把代码给大家贴出来,一起分享一下下啦. package com.example.foreveross.off ...

  10. C# 中奇妙的函数–7. String Split 和 Join

    很多时候处理字符串数据,比如从文件中读取或者存入 - 我们可能需要加入分隔符(如CSV文件中的逗号),或使用一个分隔符来合并字符串序列. 很多人都知道使用split()的方法,但使用与其对应的Join ...