幾種讀取TXT指定資料行的方法與比較

幾種讀取TXT指定資料行的方法與比較

最近看到有網友在問說,要怎麼去讀取文字檔裡的某一行資料,目前有幾個方法可以做到,而這幾種有那些效能資源上的差異.

 

測試檔 :

資料行數 : 1,000,000

內容 : GUID

容量 : 36.2 MB

 

測試讀取最後一行.

 

方法 :

1. StreamReader.ReadLine


string str = "";
using (StreamReader sr = new StreamReader(FileName))
{
	int i = 0;
	while ((str = sr.ReadLine()) != null)
	{
		if (i == ReadRow)
		{
			break;
		}
		else
		{
			i++;
		}
	}
	sr.Close();
}

耗時 : 0.85秒

記憶體用量 : 128 KB

 

2. File.ReadAllLines

string str = File.ReadAllLines(FileName)[ReadRow];

耗時 : 1.7 秒

記憶體用量 : 97,700 KB

 

3. StreamReader.ReadToEnd()


string str = "";
using (StreamReader sr = new StreamReader(FileName))
{
	str = sr.ReadToEnd().Split('\n')[ReadRow];
	sr.Close();
}

耗時 : 2.6 秒

記憶體用量 : 175,740 KB

 

第一個方法最快,記憶體用量最少,第二個方法次之,第三個方法最差.

這三種方法都是從頭讀到尾,因為是讀取最後一行,第一種之所以記憶體用量不大,主要是因為ReadLine是一次讀一行,讀完就放在變數裡,它本身不會保留,就像是DataReader一樣的方法,而第二種方式,雖然我們有指定第幾個陣列(File.ReadAllLines是回傳string array),但它還是會全部先讀進來放到string array,我們再從這array取值,而第三種做法也是跟第二種是一樣的,但它的記憶體用量及耗時幾乎是兩倍,StreamReader.ReadToEnd會先放到string去,但因為.Splite(),而又多了一個string array,所以記憶體耗量硬是比第二種還多快一半,而第二種的做法就像是DataAdapter.Fill.

 

這記憶體的耗量,就像之前那篇的string與StringBuilder的狀況一樣,記憶體配置也是一個很重要的效能成本,第一種的做法,記憶體沒什麼重新配置的問題,而第二跟第三種的用量都很大,記憶體重新配置的情況就較為嚴重,第三種又比第二種還嚴重.

 

記得剛入這業界前,有去補習班上課,那時老師就跟我們說了一句"DataReader的效能比DataAdapter好",我們當然很好奇的問為什麼,可是老師只說這是微軟說的,實際也不清楚,今天在讀取這個指定資料行時,又被我想起這句話,DataReader是online的讀取方式,當使用DataReader時,Connection不可以Close,必需為Open,而Read完的資料也不會一直佔著記憶體(除非有去存),而DataAdapter為offline的方式,Fill時,會自動open connection,把資料完整讀到DataSet或DataTable後,就會自動close connection,而這DataSet/Table就會佔著記憶體.

為什麼一次性讀完的DataAdapter,會比一筆一筆讀的DataReader效能差?這感覺怎麼跟這次讀取指定資料行的情況一樣,雖然不確定,但記憶體配置的成本也會導致這兩者的效能有如此的差異.

 

不管如何,目前知道的讀取指定文字檔的資料行有這幾種方法,如果有其它方法或心得,或是以上內容有誤的部份,也歡迎交流~

 

原始碼 : ReadLine.rar