<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      C# 溫故而知新:Stream篇(六)

      C# 溫故而知新:Stream篇(

      BufferedStream

      目錄:

       

       

       

       

      1 簡單介紹一下BufferedStream

      在前幾章的講述中,我們已經能夠掌握流的基本特性和特點,一般進行對流的處理時系統肩負著IO所帶來的開銷,調用十分頻繁

      這時候就應該想個辦法去減少這種開銷,而且必須在已有Stream進行擴展,有了以上2點需求,那么我們今天的主題,

      BufferedStream閃亮登場了,BufferedStream能夠實現流的緩存,換句話說也就是在內存中能夠緩存一定的數據而不是

      時時給系統帶來負擔,同時BufferedStream可以對緩存中的數據進行寫入或是讀取,所以對流的性能帶來一定的提升

      但是無法同時進行讀取或寫入工作,如果不使用緩沖區也行,BufferedStream能夠保證不用緩沖區時不會降低因緩沖區帶來

      的讀取或寫入性能的下降

       

      2 如何理解緩沖區

      緩沖區是內存中的一塊連續區域,用來緩存或臨時存儲數據,也就是說流可以通過緩沖區逐步對數據進行讀取或寫入操作,

      BufferedStream 中的緩存區可以由用戶設定,其表現形式為byte數組,想象下沒有緩存區將是很可怕的,假如我們的

      非固態硬盤沒有緩沖區,如果我們下載速度達到驚人的10m左右,那么下載一個2G或更大的文件時,磁頭的讀寫是非常

      的頻繁,直接的結果是磁頭壽命急劇減少,甚至將硬盤直接燒毀或者損壞

       

      3 BufferedStream的優勢

      理解了緩沖區的重要性后,讓我們在來談下BufferedStream的優勢,首先大家肯定覺的疑惑為什么MemoryStream 同樣

      也是在內存中對流進行操作,和BufferedStream有什么區別呢?BufferedStream并不是將所有內容都存放到內存中

      而MemoryStream則是BufferedStream必須跟其他流如FileStream結合使用,而MemoryStream則不用,聰明的你

      肯定能夠想到,BufferedStream必然類似于一個流的包裝類,對流進行”緩存功能的擴展包裝”,所以BufferedStream的

      優勢不僅體現在其原有的緩存功能上,更體現在如何幫助原有類實現其功能的擴展層面上

       

      4 從BufferedStream 中簡單學習下裝飾模式

      如何理解裝飾模式

                   我們在做項目時或者設計項目時常常會碰到這個問題 :我們該如何擴展已有的類功能或者如果擴展一系列派生類的

                   功能呢,可能你立刻會想到繼承,的確不錯,但是如果你仔細看下圖并且展開一定的想象的話,你就會發現繼承可能

                   導致子類的膨脹性增加,如下圖所示

                 

      首先還是得注意以下原則

      1. 多用組合,少用繼承

      利用繼承設計子類的行為,是在編譯時靜態決定的,而且所有的子類都會繼承到相同的行為。然而,如果能夠利用組合的做法擴展對象的行為,就可以在運行時動態地進行擴展。

      2. 類應設計的對擴展開放,對修改關閉。

      那么我們該如何避免子類的擴張同時又實現Girl類原有類或派生類的新功能呢?

      首先我們要達到2個目的:

      1 能夠為Girl的所有派生類都實現新功能(不修改派生類的結構)

      2 利用對象組合的方式

       

      為了滿足為Girl 類所有派生類都能使用,那么我們就加上一個Girl的裝飾類GirlWrapper:

        public abstract class GirlWrapper : Girl
          {
              protected Girl girl;
      
              public GirlWrapper(Girl thisGril)
              {
                  this.girl = thisGril;
              }
              public override void Decrorator()
              {
                  girl.Decrorator();
              }
              public override string ToString()
              {
                  return string.Format("{0}:{1}", this.girl.GirlName, this.girl.Nation);
              }
          }

      該類繼承了Girl類,從而保證了和其他派生類有共同的基本結構,

      既然有了這個裝飾類,那我們便可以刪掉原來的Singing 接口,添加一個

      SingingGirlWrapper類來實現對girl的包裝類,

          public class SingingGirlWrapper : GirlWrapper
          {
              public SingingGirlWrapper(Girl thisGril)
                  : base(thisGril)
              {
      
              }
              public void Decorator() 
              {
                  Console.WriteLine("SingingGirlWrapper decorateor:The girl named {0} who from {1} is {2} can singing nao", 
                      this.GirlName, this.Nation, this.girl.GetType().Name);
                  base.Decrorator();
              }
      
              public override string ToString()
              {
                  return base.ToString();
              }
          }

                 大家不必拘泥于派生的包裝類,你完全可以建立一個新的girl包裝類來實現特定的功能,上述例子只是演示下派生的包裝類
                這樣的話,我們便使用了組合的方式實現了既保留原有的接口(或者抽象類),又動態添加了新功能

                

      在使用時我們可以將派生類的對象放入裝飾類的構造中,這樣的話,在執行包裝類Decorator方法時,可以執行被包裝對象的

      Decorator方法和包裝類的Decorator方法從而實現對Girl派生類的包裝,這樣的話就能實現靈活的組合擴展。

      static void Main(string[] args)
              {
                  Queen queen = new Queen("Mary","Unite States");
                  SingingGirlWrapper sgw = new SingingGirlWrapper(queen);
                  sgw.Decorator();
                  Console.ReadLine();
              }


                    再次理解下裝飾模式在Stream中的作用

      通過以上的例子在回到BufferStream章節中,大家肯定一眼就看出了BufferStream其實就是上述例子中的wrapper類

      而Stream 類就是其共同的父類,為了給所有的流類提供緩沖功能所以BufferedStream便誕生了,這樣的話,我們可以

      不用修改其派生類結構,便能靈活組合將緩沖功能嵌入stream中

       

      5 BufferedStream的構造

      BufferedStream(Stream)

      其實BufferedStream的構造主要功能還是設置緩沖區大小,如果沒有指定則默認是用4096字節的進行初始化

      BufferedStream(Stream, Int32)

      第二個參數是手動指定緩沖區大小

      第一次使用此構造函數初始化 BufferedStream 對象時分配共享讀/寫緩沖區。 如果所有的讀和寫都大于或等于緩沖區大小,則不使用共享緩沖區

       

      6 BufferedStream的屬性

      *1 CanRead 已重寫。獲取一個值,該值指示當前流是否支持讀取。
      如果流支持讀取,則為 true;如果流已關閉或是通過只寫訪問方式打開的,則為 false。
      如果從 Stream 派生的類不支持讀取,則對 StreamReader、StringReader、TextReader 的 Read、ReadByte、BeginRead、EndRead 和 Peek 方法的調用將引發 NotSupportedException。
      如果該流已關閉,此屬性將返回 false。

       

      *2 CanSeek 已重寫。獲取一個值,該值指示當前流是否支持查找。
      如果流支持查找,則為 true;如果流已關閉或者如果流是由操作系統句柄(如管道或到控制臺的輸出)構造的,則為 false。
      如果從 Stream 派生的類不支持查找,則對 Length、SetLength、Position 和 Seek 的調用將引發 NotSupportedException。
      如果該流已關閉,此屬性將返回 false。

       

      *3  CanWrite 已重寫。獲取一個值,該值指示當前流是否支持寫入。
      如果流支持寫入,則為 true;如果流已關閉或是通過只讀訪問方式打開的,則為 false。 如果從 Stream 派生的類不支持寫入,

      則調用 SetLength、Write 或 WriteByte 將引發 NotSupportedException。 如果該流已關閉,此屬性將返回 false。

       

      *4  Length 已重寫。獲取流長度,長度以字節為單位。

       

      *5  Position 已重寫。獲取當前流內的位置。

       get 訪問器調用 Seek 獲取基礎流中的當前位置,然后根據緩沖區中的當前位置調整此值

       set 訪問器將以前寫入緩沖區的所有數據都復制到基礎流中,然后調用 Seek

       支持搜索到超出流長度的任何位置。

       

      7 BufferedStream的方法

      BufferStream的方法基本上和Stream類一致,沒有其獨特的方法

      關于以上方法的注意事項的大家也可參考我的第一篇

       

       簡單示例:利用socket 讀取網頁并保存在本地

          class Program
          {
              static void Main(string[] args)
              {
                  Server server = new Server("http://www.163.com/");
                  server.FetchWebPageData();
              }
          }
      
          public class Server
          {
              //端口
              const int webPort = 80;
              //默認接收緩存大小
              byte[] receiveBufferBytes = new byte[4096];
              //需要獲取網頁的url
              private  string webPageURL;
              public Server(string webPageUrl)
              {
                  webPageURL = webPageUrl;
              }
      
             /// <summary>
              ///  從該網頁上獲取數據
             /// </summary>
              public void FetchWebPageData() 
              {
                  if (!string.IsNullOrEmpty(webPageURL))
                  FetchWebPageData(webPageURL);
                  Console.ReadLine();
              }
      
              /// <summary>
              /// 從該網頁上獲取數據
              /// </summary>
              /// <param name="webPageURL">網頁url</param>
              private void FetchWebPageData(string webPageURL) 
              {
                  //通過url獲取主機信息
                  IPHostEntry iphe = Dns.GetHostEntry(GetHostNameBystrUrl(webPageURL));
                  Console.WriteLine("遠程服務器名: {0}", iphe.HostName);
                  //通過主機信息獲取其IP
                  IPAddress[] address = iphe.AddressList;
                  IPEndPoint ipep = new IPEndPoint(address[0], 80);
                  //實例化一個socket用于接收網頁數據
                  Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                  //連接
                  socket.Connect(ipep);
                  if (socket.Connected)
                  {
                      //發送頭文件,這樣才能下載網頁數據
                      socket.Send( Encoding.ASCII.GetBytes( this.GetHeader(webPageURL)));
                  }
                  else { return; }
                  //接收頭一批數據
                  var count = socket.Receive(receiveBufferBytes);
                  //轉化成string 
                  var getString = Encoding.Default.GetString(receiveBufferBytes);
                 //創建文件流
                  FileStream fs = new FileStream(@"d:\\Test.html", FileMode.OpenOrCreate);
                  //創建緩存流
                  BufferedStream bs = new BufferedStream(fs);
                  using (fs)
                  {
                      using (bs)
                      {
                          byte[] finalContent = Encoding.Default.GetBytes(getString.ToCharArray());
                          //將頭一批數據寫入本地硬盤
                          bs.Write(finalContent, 0, finalContent.Length);
                          //循環通過socket接收數據
                          while (count > 0)
                          {
                              count = socket.Receive(receiveBufferBytes, receiveBufferBytes.Length, SocketFlags.None);
                              //直接將獲取到的byte數據寫入本地硬盤
                              bs.Write(receiveBufferBytes, 0, receiveBufferBytes.Length);
                              Console.WriteLine(Encoding.Default.GetString(receiveBufferBytes));
                          }
                          bs.Flush();
                          fs.Flush();
                          bs.Close();
                          fs.Close();
                      }
                  }
              }
              /// <summary>
              /// 得到header
              /// </summary>
              /// <param name="url">網頁url</param>
              /// <returns>header字符串</returns>
              private string GetHeader(string webPageurl) 
              {
                  return "GET " + GetRelativeUrlBystrUrl(webPageurl) + " HTTP/1.1\r\nHost: "
                      + GetHostNameBystrUrl(webPageurl) + "\r\nConnection: Close\r\n\r\n";
              }
      
              /// <summary>
              /// 得到相對路徑
              /// </summary>
              /// <param name="strUrl">網頁url</param>
              /// <returns></returns>
              private string GetRelativeUrlBystrUrl(string strUrl)
              {
                  int iIndex = strUrl.IndexOf(@"//");
                  if (iIndex <= 0)
                      return "/";
                  string strTemp = strUrl.Substring(iIndex + 2);
                  iIndex = strTemp.IndexOf(@"/");
                  if (iIndex > 0)
                      return strTemp.Substring(iIndex);
                  else
                      return "/";
              }
              /// <summary>
              /// 根據Url得到host
              /// </summary>
              /// <param name="strUrl">網頁url</param>
              /// <returns></returns>
              private string GetHostNameBystrUrl(string strUrl)
              {
                  int iIndex = strUrl.IndexOf(@"//");
                  if (iIndex <= 0)
                      return "";
                  string strTemp = strUrl.Substring(iIndex + 2);
                  iIndex = strTemp.IndexOf(@"/");
                  if (iIndex > 0)
                      return strTemp.Substring(0, iIndex);
                  else
                      return strTemp;
              }
      
          }

      本章總結

      本章主要講述了BufferedStream的概念包括緩沖區等等,其中穿插了裝飾器模式的簡單介紹,希望大家能夠BufferedStream有更深的理解,寫文不容易,

      也請大家多多關注,下一章節將介紹常用的壓縮流(非微軟類庫),謝謝大家支持!

       

      posted @ 2012-04-25 20:40  逆時針の風  閱讀(18096)  評論(30)    收藏  舉報
      主站蜘蛛池模板: 成人无码www在线看免费| 国产精品日本一区二区不卡视频| 99久久久国产精品免费无卡顿| 少妇人妻偷人精品免费| 99在线视频免费观看| 亚洲国产午夜理论片不卡| 久久99国内精品自在现线| 乌什县| 日韩中文字幕一区二区不卡| 三级国产在线观看| 亚洲国产欧美在线人成AAAA | 最新中文乱码字字幕在线| 摸丰满大乳奶水www免费| 国产亚洲精品久久久久秋霞| 精品人妻少妇嫩草av专区| 亚洲精品无码你懂的网站| 国产日韩av二区三区| 久久国内精品自在自线91| 国产高清在线精品一区不卡| 精品国产午夜福利在线观看| 国产中文三级全黄| 欧美人与动牲交a免费| 日韩最新中文字幕| 新建县| 国产成人一区二区三区视频免费| 中国熟妇毛多多裸交视频| 欧美丰满熟妇hdxx| 欧美性xxxxx极品| 国产午夜福利精品片久久| 亚洲精品97久久中文字幕无码| 国产中文字幕日韩精品| 少妇高潮尖叫黑人激情在线| 中文字幕无码人妻aaa片| 日韩中文字幕人妻一区| 国产色无码专区在线观看| 国产a在亚洲线播放| 狠狠色噜噜狠狠狠狠777米奇| 亚洲欧洲av一区二区| 午夜免费无码福利视频麻豆| 国产人妻精品无码av在线| 狠狠色噜噜狼狼狼色综合久|