回答
如果它是一個大的文件,是否有可能只是尋找文件的結尾,並檢查字符'\ n'的反向字符?我知道\ n和\ r \ n存在。我掀起了下面的代碼,並在一個相當簡單的文件上測試。你可以嘗試對你有的文件進行測試嗎?我知道我的解決方案看起來很長,但我認爲你會發現它比從頭開始閱讀並重寫整個文件要快。
public static void Truncate(string file, int lines)
{
using (FileStream fs = File.Open(file, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
{
fs.Position = fs.Length;
// \n \r\n (both uses \n for lines)
const int BUFFER_SIZE = 2048;
// Start at the end until # lines have been encountered, record the position, then truncate the file
long currentPosition = fs.Position;
int linesProcessed = 0;
byte[] buffer = new byte[BUFFER_SIZE];
while (linesProcessed < linesToTruncate && currentPosition > 0)
{
int bytesRead = FillBuffer(buffer, fs);
// We now have a buffer containing the later contents of the file
for (int i = bytesRead - 1; i >= 0; i--)
{
currentPosition--;
if (buffer[i] == '\n')
{
linesProcessed++;
if (linesProcessed == linesToTruncate)
break;
}
}
}
// Truncate the file
fs.SetLength(currentPosition);
}
}
private static int FillBuffer(byte[] buffer, FileStream fs)
{
if (fs.Position == 0)
return 0;
int bytesRead = 0;
int currentByteOffset = 0;
// Calculate how many bytes of the buffer can be filled (remember that we're going in reverse)
long expectedBytesToRead = (fs.Position < buffer.Length) ? fs.Position : buffer.Length;
fs.Position -= expectedBytesToRead;
while (bytesRead < expectedBytesToRead)
{
bytesRead += fs.Read(buffer, currentByteOffset, buffer.Length - bytesRead);
currentByteOffset += bytesRead;
}
// We have to reset the position again because we moved the reader forward;
fs.Position -= bytesRead;
return bytesRead;
}
由於您只在刪除文件的末尾計劃,似乎浪費改寫一切,尤其是如果它是一個大文件和小N.當然,人們可以使論點是,如果有人想消除所有線路,然後從頭到尾更高效。
謝謝你,明天我會嘗試第一件事,但它看起來會做我所需要的 – 2012-03-09 05:42:55
工作得很好。感謝大家的幫助。 – 2012-03-09 06:08:53
您並不真正閱讀INTO StreamReader。事實上,對於你要求的模式,根本不需要StreamReader。有System.IO.File具有有用的靜態方法「readlines方法」,你可以改爲利用:
IEnumerable<string> allBut = File.ReadLines(path).Reverse().Skip(5).Reverse();
以前的版本有缺陷,早在迴應評論跟帖
List<string> allLines = File.ReadLines(path).ToList();
IEnumerable<string> allBut = allLines.Take(allLines.Count - 5);
你建議將整個文件作爲高性能替代文件(ReadLines.Count _will_讀取整個文件)? – 2012-03-09 03:34:14
你說得對。我只是通過一些定時測試來運行它。第二種方法始終更快。謝謝。更新我的答案以刪除第一個選項。 – xcud 2012-03-09 03:47:27
+1 - 雖然通過在查找Chr(13) - 1字節時逐字節地逐字節處理它可能會變得更高性能,但這應該仍然比替代方法快。 – 2012-03-09 03:58:13
既然你是指在文件中的行,我假設它是一個文本文件。如果你只是想獲得的線,你可以閱讀到一個字符串數組,像這樣:
string[] lines = File.ReadAllLines(@"C:\test.txt");
或者,如果你真的需要StreamReaders工作:
using (StreamReader reader = new StreamReader(@"C:\test.txt"))
{
while (!reader.EndOfStream)
{
Console.WriteLine(reader.ReadLine());
}
}
「StreamReader」的使用應該足以假定OP正在討論文本。 – 2012-03-09 03:32:12
我想我不確定詢問問題的人是否知道他們需要StreamReader,或者只知道他們需要閱讀文件並在線進行快速搜索並看到StreamReader出現。但是,是的,你是正確的 – BryanJ 2012-03-09 04:37:29
- 1. 閱讀流中的第一行並將其從流中刪除
- 2. 刪除行後X行PHP
- 3. 如何最後一行從數據流命令行刪除
- 4. 從表中刪除X行
- 5. 從url流問題中讀取最後n行
- 6. 從最後一行中刪除逗號
- 7. 刪除最後發生的模式行
- 8. Oledb數據讀取器讀取Excel文檔中刪除的行
- 9. 從文本中讀取最後2行
- 10. 從文件中讀取最後一行
- 11. 從文件中讀取最後N行
- 12. 刪除最後一行從的QTextEdit
- 13. 從文件中讀取行,處理它,然後將其刪除
- 14. Smarty讀取數組中的最後x個行數
- 15. 從bash中的文件讀取的行中刪除換行符
- 16. 從csv刪除最後一行
- 17. 從jTextPane刪除最後一行
- 18. 讀取和刪除X線在文件
- 19. 如何刪除csv文件中的第一個X和最後一個X行?
- 20. 從流中讀取數據的最有效方式
- 21. 如何使用流讀取器獲取X行
- 22. 刪除datagridview中的最後一行
- 23. 刪除表中的最後一行android
- 24. 刪除句子中的最後一行
- 25. 刪除表中的最後一行 - SQL
- 26. 讀取數組vb.net中最後一個X行數
- 27. 從已刪除的文件中讀取
- 28. tsql - 刪除最後一行
- 29. tableview刪除最後一行
- 30. Datagridview刪除最後一行
從文件末尾讀取x個換行符,然後從該文件的開頭讀取,直到該位置。 – 2012-03-09 03:22:12
您計劃從文件中讀取的記錄是否存在某種統一性(常見記錄長度,除\ n之外的任何內容)? – 2012-03-09 03:37:53