2015-06-08 108 views
4

我有一個非常長的文本文件。所有行都具有相同的長度。我想在C#中讀取第一百萬行,而不先讀取先前的999999行,否則程序變得太慢。我能怎麼做?在C#中讀取第一百萬行

回答

4

你知道每行有字節嗎?

NB瞭解字符數量是不夠的。

如果你知道這是個字節固定數量的使用:

using(Stream stream = File.Open(fileName, FileMode.Open)) 
{ 
    stream.Seek(bytesPerLine * (myLine - 1), SeekOrigin.Begin); 
    using(StreamReader reader = new StreamReader(stream)) 
    { 
     string line = reader.ReadLine(); 
    } 
} 

如果沒有,那麼:

string line = File.ReadLines(FileName).Skip(999999).Take(1).First(); 

雖然這第二個選項仍然需要被列舉的線條,它避免了閱讀整個文件一次全部存入內存中以便這樣做。

+8

請提供說明該代碼如何解決「沒有先讀取先前的999999」? –

+1

這是一個可怕的答案。您的示例將所有行讀入內存,然後跳過內存中的999,999個項目,以便它可以取1個項目。你做一個「Take」,然後是「First」。如果你正在做'First',那麼省略Take(1)'片。無論哪種方式,你的答案都與OP所要求的完全相反。 –

+0

@JohnathonSullinger謝謝您的評論,請參閱我的更新 – Tom

14

試試這個

const int BYTES_PER_LINE = 120; 
static void Main(string[] args) 
{ 
    StreamReader reader = new StreamReader("FileName", Encoding.UTF8); 
    long skipLines = 999999; 

    reader.BaseStream.Position = skipLines * BYTES_PER_LINE; 
}​ 
+0

確保包含每行可能返回的0x0D和/或0x0A。通常我使用較大的數字前設置1跳躍行和測試。 – jdweng

1
streamReader.BaseStream.Seek(skip_lines_offset, SeekOrigin.Begin); 

string line = streamReader.ReadLine(); 

Seek方法避免讀取整個文件。您可以閱讀更多hereskip_lines_offset是行的字節偏移量,所以number_of_skipped_lines * bytes_In_Line

+1

通常情況下,如果答案包含對代碼打算做什麼的解釋,以及爲什麼解決問題而不介紹其他問題,答案會更有幫助。 (這篇文章被至少一個用戶標記,大概是因爲他們認爲沒有解釋的答案應該被刪除。) –