Читать большой текстовый файл до определенной строки
Во-первых: извините за мой плохой английский, я немец.
У меня есть большой текстовый файл, разделенный строками (не разделенный одиночными символами), как это:
Первые данные[строка-разделитель]второй данных[строка-разделитель] ...
Я не хочу загружать весь файл в память из-за его размера (~250 МБ). Если я прочитаю весь файл с System.IO.File.ReadAllText
, я получу OutOfMemoryException
.
Поэтому я хочу прочитать файл до первого появления [STRING-SEPERATOR]
, а затем перейти к следующему строка. Это все равно, что" взять " first data
из файла, обработать его и продолжить с second data
, который теперь является первыми данными файла.
System.IO.StreamReader.ReadLine()
мне не помогает, потому что содержимое файла-одна строка.
У вас есть идея, как читать файл до определенной строки в .NET?
Я надеюсь на некоторые идеи, спасибо.
4 ответа:
Это должно помочь вам.
private IEnumerable<string> ReadCharsByChunks(int chunkSize, string filePath) { using (FileStream fs = new FileStream(filePath, FileMode.Open)) { byte[] buffer = new byte[chunkSize]; int currentRead; while ((currentRead = fs.Read(buffer, 0, chunkSize)) > 0) { yield return Encoding.Default.GetString(buffer, 0, currentRead); } } } private void SearchWord(string searchWord) { StringBuilder builder = new StringBuilder(); foreach (var chars in ReadCharsByChunks(2, "sample.txt"))//Can be any number { builder.Append(chars); var existing = builder.ToString(); int foundIndex = -1; if ((foundIndex = existing.IndexOf(searchWord)) >= 0) { //Found MessageBox.Show("Found"); builder.Remove(0, foundIndex + searchWord.Length); } else if (!existing.Contains(searchWord.First())) { builder.Clear(); } } }
Текстовый файл также может быть прочитан символьно, как описано в этом вопросе. Для поиска определенной строки вам придется использовать некоторую логику, реализованную вручную, которая может искать нужную строку на основе символьного ввода, что может быть сделано с помощью государственной машины.
StreamReader.Чтение имеет некоторые перегрузки, которые могут помочь вам. Попробуйте это:
int index, count; index = 0; count = 200; // or whatever number you think is better char[] buffer = new char[count]; System.IO.StreamReader sr = new System.IO.StreamReader("Path here"); while (sr.Read(buffer, index, count) > 0) { /* check if buffer contains your string seperator, or at least some part of it if it contains a part of it, you need check the rest of the stream to make sure it's a real seporator do your stuff, set the index to one character after the last seporator. */ }
Спасибо за ответы. Вот функция, в которой я написал: VB.NET:
Public Function ReadUntil(Stream As System.IO.FileStream, UntilText As String) As String Dim builder As New System.Text.StringBuilder() Dim returnTextBuilder As New System.Text.StringBuilder() Dim returnText As String = String.Empty Dim size As Integer = CInt(UntilText.Length / 2) - 1 Dim buffer(size) As Byte Dim currentRead As Integer = -1 Do Until currentRead = 0 Dim collected As String = Nothing Dim chars As String = Nothing Dim foundIndex As Integer = -1 currentRead = Stream.Read(buffer, 0, buffer.Length) chars = System.Text.Encoding.Default.GetString(buffer, 0, currentRead) builder.Append(chars) returnTextBuilder.Append(chars) collected = builder.ToString() foundIndex = collected.IndexOf(UntilText) If (foundIndex >= 0) Then returnText = returnTextBuilder.ToString() Dim indexOfSep As Integer = returnText.IndexOf(UntilText) Dim cutLength As Integer = returnText.Length - indexOfSep returnText = returnText.Remove(indexOfSep, cutLength) builder.Remove(0, foundIndex + UntilText.Length) If (cutLength > UntilText.Length) Then Stream.Position = Stream.Position - (cutLength - UntilText.Length) End If Return returnText ElseIf (Not collected.Contains(UntilText.First())) Then builder.Length = 0 End If Loop Return String.Empty End Function