C# Notizen 13 文件和流

.NET Framework將文件視為數(shù)據(jù)流。流是一系列用字節(jié)表示的數(shù)據(jù)分組。數(shù)據(jù)流有底層存儲(chǔ)介質(zhì),這些存儲(chǔ)介質(zhì)通常稱(chēng)為支撐存儲(chǔ)空間(backing store),它們?yōu)榱魈峁┝嗽础K业氖牵?NET Framework提供了File、Directory和Path類(lèi),這使得處理文件和目錄更容易。
命名空間 System.IO 包含處理緩沖流和非緩沖流所需的所有類(lèi)。緩沖流讓操作系統(tǒng)創(chuàng)建內(nèi)部緩沖區(qū),并使用它以效率最高的增量讀寫(xiě)數(shù)據(jù)。
本章介紹如何處理文件;使用File、Directory和Path類(lèi)來(lái)查看和管理文件系統(tǒng)以及讀寫(xiě)文件;還將介紹如何使用Stream類(lèi)及其派生類(lèi)來(lái)執(zhí)行復(fù)雜的讀寫(xiě)操作。

一、文件和目錄
可將文件視為字節(jié)序列,它有明確的名稱(chēng)和固定的支撐存儲(chǔ)介質(zhì)。要操作文件,需要使用路徑、磁盤(pán)存儲(chǔ)空間、文件名和目錄名。.NET Framework在命名空間System.IO中提供了多個(gè)類(lèi),能夠輕松地處理文件。
1.1 使用路徑
路徑是一個(gè)字符串,指出了文件或目錄的位置,可包含絕對(duì)位置信息,也可包含相對(duì)位置信息。絕對(duì)路徑指定了完整的位置,而相對(duì)路徑只指定了部分位置。使用相對(duì)路徑查找指定的文件時(shí),將以當(dāng)前位置為起點(diǎn)。
ps:當(dāng)前位置
每個(gè)進(jìn)程都有進(jìn)程級(jí)當(dāng)前位置,這通常是加載進(jìn)程的位置,但并非總是如此。
Path類(lèi)提供了一些靜態(tài)方法,讓您能夠以跨平臺(tái)的方式處理路徑字符串。雖然Path類(lèi)的大多數(shù)成員都不與文件系統(tǒng)交互,但是驗(yàn)證指定路徑字符串是否包含有效的字符。
下表列出了Path類(lèi)中常用的方法:

方法 描述
ChangeExtension 修改擴(kuò)展名
Combine 將多個(gè)字符串合并成路徑
GetDirectoryName 獲取指定路徑中的目錄
GetExtension 獲取指定路徑中的擴(kuò)展名
GetFileName 獲取指定路徑中的文件名和擴(kuò)展名
GetFlieNameWithoutExtension 獲取指定路徑中的文件名,但不包含擴(kuò)展名
GetPathRoot 獲取指定路徑的根目錄
GerRandomFileName 獲取一個(gè)隨機(jī)名稱(chēng)
GetTempFileName 穿件一個(gè)隨機(jī)命名且唯一的臨時(shí)文件,并返回該文件的完整路徑
GetTempPath 獲取指向臨時(shí)文件夾的路徑

1.2 特殊目錄
Windows操作系統(tǒng)包含很多經(jīng)常被應(yīng)用程序使用的特殊文件夾。通常,這些文件夾是由操作系統(tǒng)指定的,但安裝Windows操作系統(tǒng)時(shí),用戶也可顯式地指定它們。因此,這些文件夾的名稱(chēng)和位置可能隨計(jì)算機(jī)而異。
要確定這些特殊文件夾(如 Windows 文件夾)的路徑,最合適的方式是使用方法Environment.GetFolderPath。這個(gè)方法接受一個(gè)Environment.SpecialFolder枚舉值作為參數(shù),該參數(shù)指出了要獲取哪個(gè)特殊文件夾的路徑。
下表列出了一些常用的Environment.SpecialFolder枚舉值

枚舉值 描述
ApplicationData 用于存儲(chǔ)當(dāng)前漫游用戶使用的應(yīng)用程序數(shù)據(jù)的目錄
CommonApplicationData 用于存儲(chǔ)所有用戶共用的應(yīng)用程序數(shù)據(jù)的目錄
LocalApplicationData 用于存儲(chǔ)當(dāng)前非漫游用戶使用的應(yīng)用程序數(shù)據(jù)的目錄
CommonDocuments 包含所有用戶共用文檔的文件系統(tǒng)目錄
Desktop 邏輯桌面,而不是物理文件系統(tǒng)位置
DesktopDirectory 實(shí)際存儲(chǔ)桌面文件對(duì)象的目錄,不要將其與虛擬文件夾Desktop混為一談
MyDocuments “我的文檔”文件夾,與Personal等價(jià)
Personal 用作文檔倉(cāng)庫(kù)的目錄
System System目錄
Windows Windows或SYSROOT目錄,對(duì)應(yīng)于環(huán)境變量%windir%或%SYSTEMROOT%

1.3 DirectoryInfo和FileInfo類(lèi)
DirectoryInfo和FileInfo類(lèi)都是從FileSystemInfo派生而來(lái)的,而FileSystemInfo類(lèi)可表示文件或目錄,包含用于操作文件和目錄的方法。實(shí)例化 FileSystemInfo 類(lèi)時(shí),將緩存目錄或文件信息,因此必須使用Refresh方法進(jìn)行刷新,以確保信息是最新的。
DirectoryInfo 的實(shí)例成員提供了很多屬性和執(zhí)行常見(jiàn)操作(如復(fù)制、移動(dòng)、創(chuàng)建和列舉目錄)的方法。
下表列出了DirectoryInfo類(lèi)的常用方法和屬性:

成員 描述
Create 創(chuàng)建目錄
CreateSubdirectory 在指定路徑中創(chuàng)建子目錄
Delete 刪除當(dāng)前目錄,并可指定是否要?jiǎng)h除其中的所有文件和子目錄
EnumerateDirectories 獲取一個(gè)可枚舉集合,其中包含當(dāng)前目錄中的目錄信息
EnumerateFiles 獲取一個(gè)可枚舉集合,其中包含當(dāng)前目錄中的文件信息
EnumerateFileSystemInfos 獲取一個(gè)可枚舉集合,其中包含當(dāng)前目錄中的文件和目錄信息
Exists 指出磁盤(pán)中是否存在當(dāng)前目錄
FullName 獲取當(dāng)前目錄的完整路徑
MoveTo 將當(dāng)前目錄(包括其中的所有文件和子目錄)移到指定的位置
Name 獲取當(dāng)前目錄的名稱(chēng)
Parent 獲取當(dāng)前目錄的父目錄
Refresh 刷新緩存的目錄信息
Root 獲取路徑的根目錄部分

如下程序演示了如何使用DirectoryInfo類(lèi)執(zhí)行一些常見(jiàn)的操作:

public class DirectoryInfoExample
{
    public static void Main()
    {
        string tempPath = Path.GetTempFileName();

        DirectoryInfo directoryInfo = new DirectoryInfo(tempPath);
        try
        {
            if (directoryInfo.Exists)
            {
                Console.WriteLine("The directory already exists.");
            }
            else
            {
                directoryInfo.Create();
                Console.WriteLine("The directory was successfully created.");
                directoryInfo.Delete();
                Console.WriteLine("The directory was deleted.");
            }
        }
        catch (IOException e)
        {
            Console.WriteLine("An error occurred:{0}", e.Message);
        }
    }
}

FileInfo類(lèi)包含的實(shí)例成員提供了大量屬性和執(zhí)行常見(jiàn)文件操作(如復(fù)制、移動(dòng)、創(chuàng)建和打開(kāi)文件)的方法。
下表列出了常用的方法和屬性:

成員 描述
AppendText 創(chuàng)建一個(gè)StreamWriter,用于在當(dāng)前文件末尾追加文本
Attributes 獲取或設(shè)置當(dāng)前文件的特性
CopyTo 將當(dāng)前文件復(fù)制到新文件
Create 創(chuàng)建文件
CreateText 創(chuàng)建或打開(kāi)一個(gè)文件,以便向其中寫(xiě)入文本
Delete 刪除當(dāng)前文件
Directory 獲取父目錄
DirectoryName 獲取父目錄的名稱(chēng)
Exists 判斷磁盤(pán)中是否存在當(dāng)前文件
Extension 當(dāng)前文件的擴(kuò)展名
FullName 獲取當(dāng)前文件的完整路徑
IsReadOnly 獲取或設(shè)置一個(gè)值,這個(gè)值決定了當(dāng)前文件是否是只讀的
Length 當(dāng)前文件的長(zhǎng)度
MoveTo 將當(dāng)前文件移到指定的位置
Name 獲取當(dāng)前文件的名稱(chēng)
Open 打開(kāi)一個(gè)文件
OpenRead 打開(kāi)一個(gè)現(xiàn)有的文件以便讀取
OpenText 打開(kāi)一個(gè)現(xiàn)有的文本文件以便讀取
OpenWrite 打開(kāi)一個(gè)現(xiàn)有的文件以便寫(xiě)入
Refresh 刷新緩存的文件信息
Replace 使用當(dāng)前文件的內(nèi)容替換指定文件的內(nèi)容

如下程序演示了如何使用FileInfo類(lèi)執(zhí)行一些常見(jiàn)的操作:

public class FileInfoExample
{
    public static void Main()
    {
        string tempFile = Path.GetTempFileName();

        FileInfo fileInfo = new FileInfo(tempFile);
        try
        {
            if (!fileInfo.Exists)
            {
                using (StreamWriter writer = fileInfo.CreateText())
                {
                    writer.WriteLine("Line 1");
                    writer.WriteLine("Line 2");
                }
            }

            fileInfo.CopyTo(Path.GetTempFileName());
            fileInfo.Delete();
        }
        catch (IOException e)
        {
            Console.WriteLine("An error occurred: {0}", e.Message);
        }
    }
}

ps:流是可釋放的
使用完流后,務(wù)必調(diào)用Close方法釋放其占用的資源。也可將流放在一條using語(yǔ)句中,這是一種更好的方法,可確保流會(huì)被正確地關(guān)閉。

1.4 Directory和File類(lèi)
如果不想創(chuàng)建DirectoryInfo和FileInfo類(lèi)的實(shí)例,那么可以使用Directory和File類(lèi)。這些類(lèi)只提供了靜態(tài)方法,用于執(zhí)行DirectoryInfo和FileInfo支持的目錄和文件操作。

下表列出了Directory類(lèi)的常用方法:

成員 描述
CreateDirectory 創(chuàng)建指定路徑中的所有目錄
Delete 刪除指定的目錄
EnumerateDirectories 獲取一個(gè)可枚舉集合,其中包含指定路徑中的目錄名
EnumerateFiles 獲取一個(gè)可枚舉集合,其中包含指定路徑中的文件名
EnumerateFileSystemEntries 獲取一個(gè)可枚舉集合,其中包好指定路徑中所有文件和子目錄的名稱(chēng)
Exists 指出指定的路徑是否存在于磁盤(pán)中
GetCurrentDirectory 獲取當(dāng)前工作目錄
GetDirectoryRoot 獲取當(dāng)前路徑的卷信息、根信息或兩者
GetLogicalDrives 獲取當(dāng)前計(jì)算機(jī)中的邏輯驅(qū)動(dòng)器的名稱(chēng)
GetParent 獲取指定路徑的父目錄
Move 將文件或目錄(包括其中的所有文件和子目錄)移到指定位置

如下程序執(zhí)行的一些操作,但使用的是Directory類(lèi),而不是DirectoryInfo類(lèi):

public class DirectoryInfoExample
{
    public static void Main()
    {
        string tempPath = Path.GetTempFileName();

        try
        {
            if (DirectoryInfo.Exists(tempPath))
            {
                Console.WriteLine("The directory already exists.");
            }
            else
            {
                DirectoryInfo.CreateDircectory(path);
                Console.WriteLine("The directory was successfully created.");
                DirectoryInfo.Delete(path);
                Console.WriteLine("The directory was deleted.");
            }
        }
        catch (IOException e)
        {
            Console.WriteLine("An error occurred:{0}", e.Message);
        }
    }
}

Directory 和 DirectoryInfo 類(lèi)之間的一個(gè)重要差別體現(xiàn)在方法 EnumerateFiles、EnumerateDirectories和EnumerateFileSystemEntries。在Directory類(lèi)中,這些方法返回一個(gè)包含目錄和文件名的 IEnumerable<string>,而在 DirectoryInfo 類(lèi)中,這些方法分別返回IEnumerable<FileInfo>、IEnumerable<DirectoryInfo>和IEnumerable<FileSystemInfo>。

下表列出了File類(lèi)的常用方法

成員 描述
AppendAllLines 在文件末尾追加文本行,然后關(guān)閉文件
AppendAllText 將指定的字符串追加到文件末尾,如果文件不存在,就創(chuàng)建它
AppendText 創(chuàng)建一個(gè)StreamWriter,用于將文本追加到當(dāng)前文件末尾
Copy 將現(xiàn)有文件復(fù)制到新文件
Create 創(chuàng)建一個(gè)文件
CreateText 創(chuàng)建或打開(kāi)一個(gè)文件,以便寫(xiě)入文本
Delete 刪除指定的文件
Exists 確定指定的文件是否存在于磁盤(pán)中
GetAttributes 獲取指定文件的特性
Move 將指定文件移到新位置
OpenRead 打開(kāi)一個(gè)現(xiàn)有的文件以便讀取
OpenText 打開(kāi)一個(gè)現(xiàn)有的文本文件以便讀取
OpenWrite 打開(kāi)一個(gè)現(xiàn)有的文件以便寫(xiě)入
ReadAllBytes 打開(kāi)一個(gè)二進(jìn)制文件,將其內(nèi)容讀取到一個(gè)字節(jié)數(shù)組中,然后關(guān)閉該文件
ReadAllLines 打開(kāi)一個(gè)文本文件,將所有行都讀取到一個(gè)字符串中,然后關(guān)閉該文件
ReadAllText 打開(kāi)一個(gè)文本文件,將所有行都讀取到一個(gè)字符串中,然后關(guān)閉該文件
ReadLines 讀取文件中的行
Replace 使用其他文件的內(nèi)容替換指定文件的內(nèi)容
SetAttributes 設(shè)置指定文件的特性
WriteAllBytes 創(chuàng)建一個(gè)新文件,將指定字節(jié)寫(xiě)入其中,然后關(guān)閉該文件
WriteAllLines 創(chuàng)建一個(gè)新的文本文件,將一個(gè)或多個(gè)字符串寫(xiě)入其中,然后關(guān)閉該文件
WriteAllText 創(chuàng)建一個(gè)新文件,將指定字符串寫(xiě)入其中,然后關(guān)閉該文件

以下示例使用了使用File類(lèi)

public class FileExample
{
    public static void Main()
    {
        string tempFile = Path.GetTempFileName();

        try
        {
            if (!File.Exists(tempFile))
            {
                using (StreamWriter writer = File.CreateText(tempFile))
                {
                    writer.WriteLine("Line 1");
                    writer.WrtieLine("Line 2");
                }
            }

            File.Copy(tempFile, Path.GetTempFileName());
            File.Delete(tempFile);
        }
        catch (IOException e)
        {
            Console.WriteLine("An error occurred: {0}", e.Message);
        }
    }
}

二、讀寫(xiě)數(shù)據(jù)
要處理文件中的數(shù)據(jù),無(wú)論是讀取還是寫(xiě)入,都可以使用 Stream 類(lèi)表示的流。.NET Framework中所有基于類(lèi)的流都是從這個(gè)類(lèi)派生而來(lái)的。
下表列出了Stream類(lèi)的常用成員:

成員 描述
CanRead 之處當(dāng)前流是否支持讀取
CanWrite 之處當(dāng)前流是否支持寫(xiě)入
Close 關(guān)閉當(dāng)前流
CopyTo 將當(dāng)前流的內(nèi)容復(fù)制到另一個(gè)流中
Flush 清空所有緩沖區(qū),并將緩沖區(qū)的數(shù)據(jù)都寫(xiě)入支持存儲(chǔ)介質(zhì)
Read 從當(dāng)前流中讀取字節(jié)序列
Write 將一系列字節(jié)寫(xiě)入當(dāng)前流中

2.1 二進(jìn)制文件
不確定文件內(nèi)容的類(lèi)型時(shí),通常最好將其視為二進(jìn)制文件,這種文件不過(guò)是一個(gè)字節(jié)流。要從二進(jìn)制文件中讀取數(shù)據(jù),可使用File類(lèi)的靜態(tài)方法OpenRead,它返回一個(gè)FileStream:

FileStream input = File.OpenRead(Path.GetTempFileName());

然后,可對(duì)該FileStream調(diào)用Read方法,將數(shù)據(jù)讀取到指定的緩沖區(qū)中。緩沖區(qū)(buffer)是一個(gè)字節(jié)數(shù)組,可用于存儲(chǔ) Read 方法返回的數(shù)據(jù)。傳遞緩沖區(qū)、要讀取的字節(jié)數(shù)以及數(shù)據(jù)存儲(chǔ)位置相對(duì)緩沖區(qū)開(kāi)頭的偏移量后,Read方法將從支持存儲(chǔ)區(qū)讀取指定數(shù)量的字節(jié),將其存儲(chǔ)到緩沖區(qū),并返回實(shí)際讀取的字節(jié)數(shù):

byte[] buffer = new byte[1024];
int bytesRead = input.Read(buffer, 0, 1024);

當(dāng)然,從流中讀取數(shù)據(jù)并非能執(zhí)行的唯一操作。將二進(jìn)制數(shù)據(jù)寫(xiě)入流也是一種常見(jiàn)的操作,完成這種操作的方式與讀取數(shù)據(jù)類(lèi)似。首先使用File類(lèi)的OpenWrite方法打開(kāi)一個(gè)二進(jìn)制文件,以便寫(xiě)入,然后對(duì)返回的FileStream調(diào)用方法Write,將緩沖區(qū)中的數(shù)據(jù)寫(xiě)入支持存儲(chǔ)區(qū)。調(diào)用 Write 方法時(shí),需要傳遞如下參數(shù):包含要寫(xiě)入的數(shù)據(jù)的緩沖區(qū)、從離緩沖區(qū)開(kāi)頭多遠(yuǎn)的地方開(kāi)始讀取以及寫(xiě)入多少個(gè)字節(jié),如下所示。

FileStream output = File.OpenWrite(Path.GetTempFileName());
output.Write(buffer, 0, bytesRead);

如下代碼是一個(gè)完整的示例,它從一個(gè)二進(jìn)制文件中讀取數(shù)據(jù),并將數(shù)據(jù)寫(xiě)入另一個(gè)二進(jìn)制文件。這個(gè)示例不斷地讀寫(xiě)字節(jié),直到Read方法返回0,這表明再?zèng)]有字節(jié)可供讀取了。

public class BinaryReaderWriter
{
    const int BufferSize = 1024;

    public static void Main()
    {
        string tempPath = Path.GetTempFileName();
        string tempPath2 = Path.GetTempFileName();

        if (File.Exsists(tempPath))
        {
            using (FileStream input = FileExample.OpenRead(tempPath))
            {
                byte[] buffer = new byte[BufferSize];
                int bytesRead;

                using (FileStream output = File.OpenWrite(tempPath2))
                {
                    while ((bytesRead = input.Read(buffer, 0, BufferSize)) > 0)
                    {
                        output.Write(buffer, 0, bytesRead);
                    }
                }
            }
        }
    }
}

2.2 緩沖流
在前一個(gè)示例中使用FileStream時(shí),需要指定用于讀取數(shù)據(jù)的緩沖區(qū)以及該緩沖區(qū)的大小。在很多情況下,如果讓操作系統(tǒng)判斷要讀取多少個(gè)字節(jié),效率可能更高。
BufferedStream 讓操作系統(tǒng)創(chuàng)建內(nèi)部緩沖區(qū),并以它認(rèn)為效率最高的增量填充緩沖區(qū)。它仍以您提供的增量對(duì)您提供的緩沖區(qū)進(jìn)行填充,但填充時(shí)使用內(nèi)部緩沖區(qū)的數(shù)據(jù),而不直接使用支持存儲(chǔ)區(qū)中的數(shù)據(jù)。要?jiǎng)?chuàng)建緩沖流,可使用Stream創(chuàng)建一個(gè)新的BufferedStream實(shí)例,如下所示:

public class BinaryReaderWriter
{
    const int BufferSize = 1024;

    public static void Main()
    {
        string tempPath = Path.GetTempFileName();
        string tempPath2 = Path.GetTempFileName();

        if (File.Exsists(tempPath))
        {
            using (BufferedStream input = new BufferedStream(File.OpenRead(tempPath)))
            {
                byte[] buffer = new byte[BufferSize];
                int bytesRead;

                using (BufferedStream output = new BufferedStream(File.OpenWrite(tempPath2)))
                {
                    while ((bytesRead = input.Read(buffer, 0, Buffersize)) > 0)
                    {
                        output.Write(buffer, 0, bytesRead);
                    }
                }
            }
        }
    }
}

2.3 文本文件
Stream實(shí)例不僅可指向二進(jìn)制文件,還可指向文本文件,并可使用其Read和Write方法來(lái)讀寫(xiě)數(shù)據(jù)。讀寫(xiě)字節(jié)數(shù)組,而不是字符串,這樣比較不方便。為簡(jiǎn)化文本文件的處理工作,.NET Framework提供了StreamReader和StreamWriter類(lèi)。
StreamReader提供了一個(gè)Read方法,它每次讀取一個(gè)字符;還提供了一個(gè)ReadLine方法,它每次讀取一行字符,并返回一個(gè)字符串。行是一系列字符,以換行符(\n)、回車(chē)(\r)或換行和回車(chē)(\r\n)結(jié)尾。到達(dá)輸入流末尾后,ReadLine將返回null;否則返回一行字符,但不包含行尾字符。要寫(xiě)入文本數(shù)據(jù),可使用StreamWriter類(lèi)的WriteLine方法。
如下是一個(gè)讀寫(xiě)文本數(shù)據(jù)的示例:

public class TextReaderWriter
{
    public static void Main()
    {
        string tempPath = Path.GetTempFileName();
        string tempPath2 = Path.GetTempFileName();

        if (File.Exsists(tempPath))
        {
            using (StreamReader reader = new File.OpenText(tempPath))
            {
                string buffer = null;
                using (StreamWriter writer = new StreamWriter(tempPath2))
                {
                    while ((buffer = reader.ReadLine()) !=null)
                    {
                        writer.WriteLine(buffer);
                    }
                }
            }
        }
    }
}

2.4 使用File類(lèi)讀寫(xiě)數(shù)據(jù)
鑒于從文件(無(wú)論是文本還是二進(jìn)制文件)讀寫(xiě)數(shù)據(jù)是一種常見(jiàn)任務(wù),因此File類(lèi)提供了多個(gè)方法,使得這項(xiàng)任務(wù)比直接使用流更方便。
要讀寫(xiě)二進(jìn)制數(shù)據(jù),可分別使用方法ReadAllBytes和WriteAllBytes。這些方法打開(kāi)文件,讀取或?qū)懭胱止?jié),然后關(guān)閉文件。
如下程序使用的是方法ReadAllBytes和WriteAllBytes:

public class TextReaderWriter
{
    public static void Main()
    {
        string tempPath = Path.GetTempFileName();
        string tempPath2 = Path.GetTempFileName();

        if (File.Exsists(tempPath))
        {
            byte[] data = File.ReadAllBytes(tempPath);
            File.WriteAllBytes(tempPath2, data);
        }
    }
}

讀寫(xiě)文本數(shù)據(jù)也很容易。要讀取文本數(shù)據(jù),可使用方法ReadAllLines或ReadAllText;要寫(xiě)入文本數(shù)據(jù),可使用方法WriteAllLines或WriteAllText。方法ReadAllLines將文件中的所有行都讀入一個(gè)字符串?dāng)?shù)組中,其中每一行都是該數(shù)組的一個(gè)元素;而 ReadAllText 將所有行都讀入一個(gè)字符串中。
方法WriteAllLines將字符串?dāng)?shù)組的每個(gè)元素都寫(xiě)入文件,而WriteAllText將一個(gè)字符串的內(nèi)容寫(xiě)入文件。如果指定的文件存在,那么這兩個(gè)方法都覆蓋它;否則,創(chuàng)建一個(gè)新文件。要在現(xiàn)有文件末尾追加文本,可使用方法 AppendAllLines 或 AppendAllText;如果需要打開(kāi)一個(gè)流,就可使用方法AppendText。

如下程序使用方法ReadAllLines和WriteAllLines

public class TextReaderWriterFile
{
    public static void Main()
    {
        string tempPath = Path.GetTempFileName();
        string tempPath2 = Path.GetTempFileName();

        if (File.Exsists(tempPath))
        {
            string[] data = File.ReadAllLines(tempPath);
            File.WriteAllLines(tempPath2, data);
        }
    }
}

使用方法ReadAllLines或ReadAllText的缺點(diǎn)是,首先必須將整個(gè)文件讀入內(nèi)存。為解決這個(gè)問(wèn)題,可使用方法ReadLines,它返回一個(gè)IEnumerable<string>集合。由于這個(gè)方法返回一個(gè) IEnumerable<string>集合,因此可在返回整個(gè)集合前就開(kāi)始枚舉它。
如下程序使用了WriteAllLines和ReadLines:

public class TextReaderWriterFile
{
    public static void Main()
    {
        string tempPath = Path.GetTempFileName();
        string tempPath2 = Path.GetTempFileName();

        if (File.Exsists(tempPath))
        {
            File.WriteAllLines(tempPath, File.ReadLines(tempPath2));
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,983評(píng)論 6 537
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,772評(píng)論 3 422
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 176,947評(píng)論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,201評(píng)論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,960評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,350評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,406評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,549評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,104評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,914評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,089評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,647評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,340評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,753評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,007評(píng)論 1 289
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,834評(píng)論 3 395
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,106評(píng)論 2 375

推薦閱讀更多精彩內(nèi)容