2.C#知識點:I/O

来源:http://www.cnblogs.com/DingKing/archive/2017/12/20/8067335.html
-Advertisement-
Play Games

一.什麼是I/0流? 英文翻譯:Input/Output,在程式里簡單的理解為讀寫數據操作數據的意思。流操作是為瞭解決體積大數據占用太多的記憶體,就是分段進行操作。就跟我們吃飯一樣,一口一口的吃,還沒見過誰直接一口吃完的。流就是細水長流。 在我們強大的Net中,就是微軟為了簡化我們的工作,為了我們能對 ...


一.什麼是I/0流?

  英文翻譯:Input/Output,在程式里簡單的理解為讀寫數據操作數據的意思。流操作是為瞭解決體積大數據占用太多的記憶體,就是分段進行操作。就跟我們吃飯一樣,一口一口的吃,還沒見過誰直接一口吃完的。流就是細水長流。

  在我們強大的Net中,就是微軟為了簡化我們的工作,為了我們能對一系列的對象進行行操作,讀寫。NetFrameWork為我們.Net程式員提供了各種各樣的類方便我們操作。他們都在Sytem.IO這個命 名空間,我們下麵的內容就是要對這些類做詳細的說明。

二.有幾種流,這幾種流的區別是什麼,怎麼用?

1.常用的流

               文件流 FileStream

               記憶體流MemoryStream

               網路流NetworkStream

 這個三個流都是從Stream繼承下來的,還有幾個不常用的流。

2.Stream介紹

可以看到Stream類是抽象類,定義了流應有的一些基本操作的聲明,具體實現由繼承它的具體子類流實現。

屬性說明:

    Position 表示流的位置,

    Length 表示流的長度。

         CanWrite表示當前流是否可以寫入。

    CanTimeOut表示當前的流是否可以超時。

    CanSeek表示 獲取指示當前流是否支持查找功能的值。

    CanRead表示當前流是否支持讀取操作。

    ReadTimeout 設置讀取操作時候的超時時間。

    WriteTimeout 設置寫入操作的時候超時的時間。

方法說明下:

  Synchronized:MSDN 上解釋是指定的 Stream 對象周圍創建線程安全(同步)包裝。這個解釋我也不是很明白,應該就是給流包裝一下,返回值還是一個流。

  BeginRead:開始非同步讀操作,參數1:是一個byte數組,作為流的緩衝區,參數2是開始讀取的位置,第三個參數是讀取的讀取的長度。第四個參數是一個回調用委托參數,這個參數的作用,是在流讀取完成之後執行某些操作,第五個參數就是一個自定義的對象狀態。用與其他的流區分。這個參數不管它,占時我也不知道有啥用。

  BeginWrite:同理我就不說了。

  Close:我就不說了。

  CoptyToStream:從當前流中讀取位元組並將其寫入到另一流中。

  CoptyToAsync:從名字就可以看出區別的和上面的功能一樣,只是非同步讀取。

  Read:開始讀取操作,和第一個方法一樣,但是不是非同步操作,返回值是讀到的位元組數字,返回0代表,到達流的結尾,讀完了。

  Write :同理。

  ReadAsync:取代了BeginRead

  ReadByte:讀取一個位元組,並將流的位置提升一個位元組,意思就是從你讀完的地方接著讀,不會從頭讀。

  Seek:設置當前流的位置。

  SetLength:設置當前流的長度。

Stream定義的基礎方法就這麼多,各種方法還有幾個重載版本。詳細瞭解的可以去看看MSDN官方文檔。Stream類是一個抽象類,只定義方法在聲明,具體實現由派生其的子類去實現。也就是接下來要要講解的:

  文件流FileStream

  記憶體流 MemoryStream

  和網路流NetWorkStream(System.Net.Sockets命名空間下,不同於之前兩個)

3.FileStream流

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IOTest
{
    class Program
    {
        static void Main(string[] args)
        {

            //創建流實例。
            FileStream filestrem = new FileStream(@"d:\一小時小超人.txt", FileMode.Create);
            string message = "我的名字叫:一小時小超人啊";
            byte[] bytes = Encoding.UTF8.GetBytes(message);

            //寫入字元串
            filestrem.Write(bytes, 0, bytes.Length);
            
        }
    }
}

這是時候我們去D盤可以發現我們已經成功寫入了。但是這個地方有一個問題,首先我們將代碼稍微改變一下。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IOTest
{
    class Program
    {
        static void Main(string[] args)
        {

            //創建流實例。
            FileStream filestream = new FileStream(@"d:\一小時小超人.txt", FileMode.Create);
            string message = "我的名字叫:一小時小超人啊";
            byte[] bytes = Encoding.UTF8.GetBytes(message);

            //寫入字元串
            filestream.Write(bytes, 0, bytes.Length);
        Console.ReadKey();
            
        }
    }
}

註意:

  上面代碼地方標註紅色的代碼是我添加的,這時候我們再次運行時候控制台界面不會一閃而過,這個時候我們手動關閉控制台程式,然後在去D盤看我們創建的文件。您會發現這個時候,字元沒有被寫進來。這是因為流的寫入有一個緩衝區的概念。因為I0操作是很耗時的,如果讀到一個位元組,就寫一個位元組。那這樣整個過程就很慢。

  這個原理就和網站一樣。一個操作要多次請求服務端一樣。將多次請求併為一次。這樣做節約了很多性能。IO流也是一樣。它將讀取的位元組先寫到緩衝區裡面。然後一次性寫入文件。這樣節約了很大的性能。所以Write操作只是將位元組寫入緩衝區,而不是真正的寫入文件。那麼真正的寫入文件的操作是什麼呢?

  FileStrem為了我們提供了Flush這個方法將緩衝區的內容寫入文件,清除緩衝區。所以剛剛我們手動關閉控制台。導致發生異常。寫入失敗。這時候聰明的同學可能會有疑問,第一次的時候也沒有調用Flush這個方法,也成功的寫入了。這是因為什麼呢?這是因為程式正常執行結束的時候,銷毀這個對象的時候,系統會為了保證緩衝區的文件寫入文件中,會自動幫我們調用這個Flush方法,FileStream中很多地方都調用了Flush。例如:Close()和Dispose()。

  說到 FileStream的讀寫就不得不說到StreamRead和StreamWrite這個兩個是通用讀寫器類。對流的操作都可以用它。

  之前一直沒搞清楚這個與FileStream區別,感覺這個兩個差不多,但是還是有一點區別的。

  兩者最大的區別:FileStream是操作位元組和位元組數組,可以操作任何類型的文件,但是StreamRead主要操作的是字元串。

  敘述結束,從下麵掏一手代碼說話!

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IOTest
{
    class Program
    {
        static void Main(string[] args)
        {

            //創建流實例。
            FileStream filestrem = new FileStream(@"d:\一小時小超人.txt", FileMode.Create);
            //string message = "我的名字叫:一小時小超人啊";
            //byte[] bytes = Encoding.UTF8.GetBytes(message);
            ////寫入字元串
            //filestrem.Write(bytes, 0, bytes.Length);
            //Console.ReadKey();

            StreamWriter streamwriter = new StreamWriter(filestrem);
            streamwriter.WriteLine("我是帥帥的一小時小超人!");
            streamwriter.Close();


        }
    }
}

  從代碼可以很明顯在看出來,FileStream寫入的時候是操作的是byte數組,StreamWrite操作的就是字元串。這就是這兩個類的最大區別。

  StreamWrite類操作字元/字元串比較方便,但是有些場景下使用FileStream對象更合適,操作位元組都是用FileStream比較合適,StreamRead是同樣的道理占時不想詳細在說了。

  PS:知識點會都持續補充的,作為本人複習,學習,整理知識用。

 

三. Directory DirectoryInfo 和File Fileinfo,Path的作用,有什麼區別?

 

  File類和FileInfo類兩個的類的功能是差不多,都是操作文件的。可以對文件進行增刪該查讀寫,但是File類是靜態類不需要創建,所以他們的不同的應用場景就出現了,如果對文件進行單次操作的話,就用File類就好了。因為File類是靜態類不需要創建對象也不需要銷毀對象,可以減少性能開銷。

 

  這裡不明白的同學可能會和我之前一樣疑惑,既然靜態類不需要創建對象,比Fileinfo類好那麼多。那還要Fileinfo還幹嘛?那就直接用File類不就好了。其實不然,因為File類每次調用的時候都要去進行安全檢查,占用Cup,File每次都會去尋找文件性能浪費。但是FileInfo類在只會在創建的時候去尋找一次,所以顯而易見,對文件進行單步操作的時候,就是操作的一次的時候,適合使用File類。但是進行多次操作的時候,就是FileInfo更適合了,因為FileInfo雖然需要創建對象和銷毀,但是減少了每次操作要去尋找文件的消耗。所以這裡的適合與否主要是看性能。

 

  Directory和DirectoryInfo同理。

 

1.File類和FileInfo類詳細介紹介紹。

  File類的常用操作

            //創建一個文件。
            File.Create(@"D:\一小時小超人2.txt");


            //寫入方式1:結合FileStream
            FileStream fileStream = File.Create(@"D:\一小時小超人3.txt");//1.創建完了文件。往文件寫入東西。File.Create返回的是一個FileStream對象。FileStream對象可以支持往文件寫入位元組。
            string sfilecontent = "我是帥帥的小超人"; //2.這就是上面FileStream的知識點,寫入byte數組。
            byte[] bytes1 = Encoding.UTF8.GetBytes(sfilecontent);//3.將字元串轉換為位元組寫入,因為我上面的說到,FileStream和StreamWrite都可以進行寫入操作,最大的區別就是FileStream操作的是位元組,Stream操作的是字元串。
            fileStream.Write(bytes1, 0, bytes1.Length);

            //寫入方式2:集合StreamWriter
            StreamWriter streamwrite = File.CreateText(@"D:\一小時小超人4.txt");
            streamwrite.Write("我是帥帥的小超人");
            streamwrite.Close();

            //寫入方式3:File本身就支持寫入
            string sfilecontent1 = "我是酷酷的一小時小超人";
            File.WriteAllText(@"D:\一小時小超人3.txt", sfilecontent1);//註意這個操作比較適合對已經存在文件進行讀寫。如果文件不存在。根據我們前面講的File和FileInfo的區別這個地方我們應該用FileInfo
            //File.WriteAllBytes();寫入位元組
            //File.WriteAllLines();一行一行寫

  上面的代碼演示的File類的創建寫入,演示了兩種方式,FileStream的寫入位元組數組,StreamWriter寫入的是字元串。

            //讀取方式1:結合FileStream
            string txt = string.Empty;
            FileStream fs = File.OpenRead(@"D:\一小時小超人3.txt");
            byte[] bytes2 = new byte[1024];
            while (fs.Read(bytes2, 0, bytes2.Length) > 0)
            {
                txt += Encoding.UTF8.GetString(bytes2);

            }
            Console.WriteLine(txt);
            Console.ReadKey();

            //讀寫方式2:集合StreamRead
            string txt1 = string.Empty;
            StreamReader streamreader=File.OpenText(@"D:\一小時小超人4.txt");
            txt1= streamreader.ReadLine();
            while (!streamreader.EndOfStream)
            {
                txt1+= streamreader.ReadLine();
            }
            Console.WriteLine(txt1);
            Console.ReadKey();

   上面的地方演示了File的讀取。

   FileInfo類的常用操作

            FileInfo file = new FileInfo(@"D:\一小時小超人1000.txt");
            FileStream fileStream = file.Create();//創建文件,文件存在,就重新覆蓋。返回FileStream對象進行讀寫
            FileStream fileStream1 = file.OpenRead();//打開文件,如果文件不存在,則會拋出 FileNotFoundException 異常。
            FileStream fileStream2 = file.Open(FileMode.OpenOrCreate);//打開文件,但是有一個文件模式枚舉的參數可以設置。這裡我先設置了FileMode的值是OpenOrCreate,如果不存在就創建,這個方法有多個重載。詳細的請看MSDN文檔。
            StreamWriter streamread = file.CreateText();//創建文件,返回StreamWriter對象進行寫入
            StreamReader streamread1 = file.OpenText();//創建對象返回StreamReader進行讀。
            file.Delete();//刪除。

 Fileinfo類和File功能都是差不多,我簡單的在上面代碼列舉了一下各種語法,並且做了註釋。如果剛學習的小伙伴有疑問,或者書寫有誤,請在下麵幫指出來,方便我們討論,和糾錯。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 內容和表格內容一起讀; word內容: 代碼: 1 public static void ReadWordByOpenXml(string path) 2 { 3 using (WordprocessingDocument doc = WordprocessingDocument.Open(path ...
  • DBHelper類: 簡單的理解就是一個工具箱,我要用錘子的時候就在裡面拿,我要用剪刀的時候也可以在裡面拿,前提是我們寫的DBHelper夠不夠強大! 等時間充足再抽個時間出來寫這篇博客,因為最近快考試了得抓緊時間補習,如果覺得我寫的還不錯,可以關註我看我寫更多的文章。 ...
  • HashTable和Dictionary的區別 1.HashTable 哈希表(HashTable)表示鍵/值對的集合。在.NET Framework中,Hashtable是System.Collections命名空間提供的一個容器,用於處理和表現類似key-value的鍵值對,其中key通常可用來 ...
  • 1.先上效果 將所有節點加入ComboBox數據源,在ComboBox中選擇時下方Treeview顯示該節點下的子節點。 1.xaml文件,將以下代碼加入界面合適位置 2.後臺代碼 a.用於綁定的節點類 b.主界面類代碼 ...
  • 如果想支持 .xls,.xlsx 兩種格式 則必須安裝一個exe文件,下載路徑https://www.microsoft.com/zh-CN/download/details.aspx?id=13255 下載好安裝就支持.xls,.xlsx 兩種格式轉換成datatable了, 附代碼 public ...
  • 報錯信息:Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities we ...
  • 報錯信息:LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression 參考 ...
  • C# 開發環境: VisualStudio2015 資料庫: SQLserver2008 程式主界面: 註釋: lbl標簽: 程式中的lbl標簽:編號、人數、姓名、性別、請輸入要查詢的信息,這裡他們只起到了說明作用,所有命名一般為預設,只修改Text文本。 程式中的lbl標簽:編號後面的0,他起到了 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...