2017-05-02 31 views
0

下面的代碼工作得很好:讀幾行從文件一次

Function ReadLines(FN As String, n As Integer) As String() 
    Dim T(0 To n) As String 
    With My.Computer.FileSystem.OpenTextFileReader(FN) 
     For i As Integer = 0 To n 
      T(i) = .ReadLine() 
     Next 
    End With 
    Return T 
End Function 

但是,如果該文件位於遠程服務器上,這有可能成爲窘況緩慢。有沒有辦法更有效地做同樣的事情?我可以一次過讀取整個文件,但是這也是相當低效...

回答

1

BufferedStream class專門設計用於在串行讀取(或寫入)文件時減少系統IO的數量。因此,這有望使您的閱讀更有效。

Function ReadLines(FN As String, n As Integer) As String() 
    Using fs As FileStream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) 
     Using bs As New BufferedStream(fs) 
      Using sr As New StreamReader(bs) 
       Dim lines = New List(Of String)(n) 
       For i As Integer = 0 To n 
        Dim line As String = sr.ReadLine() 
        If (line Is Nothing) Then 
         Exit For 
        End If 
        lines.Add(line) 
       Next 
       Return lines.ToArray() 
      End Using 
     End Using 
    End Using 
End Function 
+0

我沒有測試它的效率,但你需要添加一個fs.close,否則你的文件將保持鎖定 – Pierre

+0

我相信'Close()'將由'Dispose()'調用,這在'最終使用' –

+0

好吧,它似乎並不那麼...至少不在我的編譯器。 – Pierre

0
Dim lines = IO.File.ReadLines(fileName). 
        Skip(firstLineIndex). 
        Take(lineCount). 
        ToArray() 

不像File.ReadAllLines方法,File.ReadLines不讀取整個文件在一個單一的操作。它將文件的內容公開爲Enumerable(Of String),但在使用該文件之前不會讀取該文件中的任何內容。該代碼將不得不閱讀每一行,直到您想要的最後一行,但不會再讀取任何內容。

說實話,我不確定它會變得多快,因爲它實際上可能使用StreamReader.ReadLine。這值得測試。另一種方法是隻讀取文件的大塊,並自行將其分解,當你至少閱讀完所需內容時停止。

+0

的'FileSystem.OpenTextFileReader'返回'StreamReader',所以我相信'File.ReadLines(...)採取(N)'是有效的與在OP代碼片段中調用'.ReadLine()''N'次相同。因此'File.ReadLines(...)。拿(N)'不會增加性能。儘管你的代碼絕對更簡潔美觀。 –

+0

它不能在我的環境下編譯(「take」不被識別),但是如果@DmitryEgorov是正確的,它無論如何都沒有用...... 關於閱讀更大的塊,這可能確實有用。我如何閱讀一定數量的字符? – Pierre