天天看點

C#檔案流FileStream的用法

1、簡介

FileStream 類:主要用于對檔案進行讀取、寫入、打開和關閉操作,并對其他與檔案相關的作業系統句柄進行操作,如管道、标準輸入和标準輸出。讀寫操作可以指定為同步或異步操作。FileStream 對輸入輸出進行緩沖,進而提高性能。——MSDN

**簡單點說:FileStream類可以對任意類型的檔案進行讀取操作,可根據需要來指定每次讀取的位元組長度(這是比File類優秀的地方之一),以此減少記憶體的消耗,提高讀取效率。

2、File和FileStream的差別

    File是一個靜态類;FileStream是一個非靜态類。

       **最直接差別:将讀取檔案比作是從A桶往B桶運水。使用File就是整個用桶倒進去,使用FileStream就是使用水管慢慢輸送,應用場景不同,大檔案推薦FileStream,不會炸記憶體。

  File:是一個檔案的類,對檔案進行操作。其内部封裝了對檔案的各種操作(MSDN:提供用于建立、複制、删除、移動和打開單一檔案的靜态方法,并協助建立FileStream對象)。

       FileStream:是一個檔案流的類,處理檔案的原始位元組,即處理byte[]。對txt,xml,avi等任何檔案進行内容寫入、讀取、複制...

3、FileStream的用法示例

3.1 注意用using主動釋放記憶體

using有兩個主要用途:

1、作為指令,用于為命名空間建立别名或導入其他命名空間中定義的類型。

2、作為語句,用于定義一個範圍,在此範圍的末尾将釋放對象,using的對象必須是實作IDisposable接口的。

這裡用到了第二種,如果一個類實作了接口IDisposable(這個接口隻有一個方法void Dispose()),當這個類在using中建立的時候,using代碼塊結束時會自動調用這個類中實作了接口IDisposable的Dispose()方法,也就是釋放資源。一般來說,檔案流都要主動釋放資源的,因為讀寫檔案是會加鎖的,不釋放的話,别的程式就無法使用檔案了,這也就是FileStream一般和using配套使用的原因。當然,也可以不用using,但是在用完後需要顯示調用三行代碼:

                          fs.Flush();//清除緩沖區

                          fs.Close();//關閉

                          fs.Dispose();//釋放

代碼示例:

static void Main(string[] args)
        {
            using (FileStream fs = new FileStream(@"C:\Users\awang\Desktop\1.txt", FileMode.OpenOrCreate, FileAccess.Read))
            {//在using中建立FileStream對象fs,然後執行大括号内的代碼段,
             //執行完後,釋放被using的對象fs(背景自動調用了Dispose)
                byte[] vs = new byte[1024];//數組大小根據自己喜歡設定,太高占記憶體,太低讀取慢。
                while (true) //因為檔案可能很大,而我們每次隻讀取一部分,是以需要讀很多次
                {
                    int r = fs.Read(vs, 0, vs.Length); 
                    string s = Encoding.UTF8.GetString(vs, 0, r);
                    Console.WriteLine(s);
                    if (r == 0) //當讀取不到,跳出循環
                    {
                        break;
                    }
                }
            }
            Console.ReadKey();
        }
           

3.2 讀檔案一般步驟

讀檔案即3.1中代碼段,其中有以下重點:

1. FileStream fs = new FileStream(@"C:\Users\awang\Desktop\1.txt", FileMode.OpenOrCreate, FileAccess.Read)

該構造函數有很多重載,上面用的是最最常用的一個。第一個參數填路徑;第二個參數選擇形式,選擇openorcreate最保險,檔案不存在就建立一個;第三個參數選read,即讀取。

2. byte[] vs = new byte[1024]

建立緩存數組,數組大小根據自己喜歡設定(注意:太高占記憶體,太低讀取慢。)

3. 循環讀取資料,對應while循環代碼(因為檔案可能很大,而我們每次隻讀取一部分,是以需要讀很多次,當讀取完後,跳出循環)。

3.3 寫檔案一般步驟

static void Main(string[] args)
        {
            string s = "寫入檔案寫入檔案寫入檔案寫入檔案寫入檔案寫入檔案";
            using (FileStream fs = new FileStream(@"C:\Users\awang\Desktop\1.txt", FileMode.OpenOrCreate, FileAccess.Write))
            {//在using中建立FileStream對象fs,然後執行大括号内的代碼段,
             //執行完後,釋放被using的對象fs(背景自動調用了dispose)
                byte[] buffer = Encoding.UTF8.GetBytes(s);      //把要寫入的東西轉換成byte數組
                fs.Write(buffer, 0, buffer.Length);          //寫入
            }
            Console.ReadKey();
        }
           

其中有以下重點:

FileStream fs = new FileStream(@"C:\Users\awang\Desktop\1.txt", FileMode.OpenOrCreate, FileAccess.Write)

第一個參數填路徑;第二個參數選擇形式,選擇openorcreate最保險,檔案不存在就建立一個;第三個參數選Write,即寫入。

3.4 複制大檔案一般步驟(讀寫同步)

static void Main(string[] args)
        {
            string sourcePath = @"C:\Users\awang\Desktop\source.mp4";//需要被複制的檔案的路徑
            string targetPath = @"C:\Users\awang\Desktop\target.mp4";//複制到的路徑
            using (FileStream fsRead = new FileStream(sourcePath, FileMode.OpenOrCreate, FileAccess.Read))
            {//建立讀取檔案的流
                using (FileStream fsWrite = new FileStream(targetPath, FileMode.OpenOrCreate, FileAccess.Write))
                {//建立寫入檔案的流
                    byte[] buffer = new byte[1024 * 1024 * 2];//緩存設定2MB;
                    while (true)//循環讀取
                    {
                        int r = fsRead.Read(buffer, 0, buffer.Length);//讀資料
                        if (r == 0)//讀不到資料了,跳出循環
                        {
                            break;
                        }
                        fsWrite.Write(buffer, 0, r);//寫資料
                    }
                }
            }
            Console.WriteLine("複制完成!");
            Console.ReadKey();
        }