Lesen Sie Große TXT-Datei, die Out-of-Memory-Ausnahme
Ich Lesen wollen große TXT-Datei eine Größe von 500 MB,
Zuerst benutze ich
var file = new StreamReader(_filePath).ReadToEnd();
var lines = file.Split(new[] { '\n' });
aber es throw out of memory-Ausnahme dann habe ich versucht zu Lesen, Zeile für Zeile, aber nach dem Lesen wieder rund 1,5 Millionen Zeilen werfen out-of-memory-Ausnahme
using (StreamReader r = new StreamReader(_filePath))
{
while ((line = r.ReadLine()) != null)
_lines.Add(line);
}
oder ich
foreach (var l in File.ReadLines(_filePath))
{
_lines.Add(l);
}
aber Wieder erhielt ich
Eine Ausnahme des Typs " System.OutOfMemoryException " ist in
"mscorlib".die dll wurde aber nicht behandelt werden, in Benutzer-code
Meine Maschine ist eine leistungsstarke Maschine mit 8GB ram also sollte es nicht werden, meine Maschine problem.
p.s: ich habe versucht, öffnen Sie diese Datei in NotePadd++ und ich erhielt 'die Datei ist zu groß, um geöffnet zu werden' Ausnahme.
Was ist der Punkt der Speicherung von allen, die in einer Sammlung?
Sie sprechen über "500 Zeilen," aber wie groß ist die Datei, in Bezug auf bytes und Zeichen? 500 Zeilen mit 80 Zeichen sollte kein problem sein - 500-Linie von einer Milliarde Zeichen pro Zeile eindeutig ist.
500-GB-Datei in 8 GB Speicher? Das wird nicht passen. Sie müssen einen anderen Weg finden, der die Verarbeitung der Datei,, die nicht erfordert, die ganze Sache in Erinnerung. Prozess pro Zeile (oder vielleicht pro kleine Menge von Linien)
Sie können das Problem beheben, indem Sie nicht laden Sie die gesamte Datei im Speicher. Klar, Ihr design ist nicht geeignet, um die Anforderungen der Anwendung. Was werden Sie schließlich mit den Daten tun? Jede Bearbeitung, Filterung etc? Vielleicht müssen Sie es speichern in eine Datenbank ersten.
InformationsquelleAutor Behnam | 2012-11-16
Du musst angemeldet sein, um einen Kommentar abzugeben.
Verwenden Sie einfach Datei.ReadLines gibt eine
IEnumerable<string>
und laden nicht alle Zeilen auf einmal in den Speicher.sind Sie sicher, dass Sie nicht immer diese Fehlermeldung aus anderen teilen des Programms. Versuchen Sie, diese in eine leere Lösung.
Ich habe soeben eine Konsole-Anwendung, die nur einer code-Zeile foreach (var line in File.ReadLines(_filePath)) { },aber es schaffen Ausnahme wieder.
Habe es gerade getestet mit 8,7 GB text-Datei(120,000,000 Linien) und funktionierte gut.
InformationsquelleAutor L.B
Die Ursache der Ausnahme zu sein scheinen wachsende _lines Sammlung, aber nicht das Lesen einer großen Datei. Sie Lesen gerade Linie und
adding to some collection _lines which will be taking memory and causing out of memory execption
. Sie können Filter anwenden, um nur die gewünschten Zeilen zu _lines Sammlung.Was Ausnahme wirft er jetzt?
OutofMemoryException
InformationsquelleAutor Adil
Edit:
laden, die ganze Datei im Speicher werden wodurch Objekte, um zu wachsen, und .net löst OOM-Ausnahmen, wenn es nicht genügend zusammenhängenden Speicher für ein Objekt.
Die Antwort ist immer noch die gleiche, müssen Sie die stream-Datei nicht Lesen Sie den gesamten Inhalt. Das erfordert eine rearchitecture Ihrer Anwendung, jedoch mit
IEnumerable<>
Methoden können Sie stapeln sich Geschäftsprozesse in verschiedenen Bereichen der Anwendungen und verzögern die Bearbeitung.Einen "leistungsstarken" Rechner mit 8 GB RAM ist nicht in der Lage sein zu speichern, eine 500-GB-Datei in den Arbeitsspeicher, 500 ist größer als 8. (plus Sie nicht 8 als Betriebssystem hält einige, man kann nicht reservieren, alle Speicher in .Net, 32-bit hat eine 2GB Grenze, die Datei öffnen und speichern, wird die Linie halten, die Daten doppelt, es ist ein Objekt-Größe-overhead....)
Können Sie nicht laden Sie die ganze Sache in den Speicher zu verarbeiten, müssen Sie die stream-Datei, die durch Ihre Verarbeitung.
In meinem zweiten Ansatz wollte ich mit StreamReader und auch mit dem entfernen _lines.Add(line); line, ich erhalte OutOfMemoryException. so habe ich nicht deutlich verstehen, was meinst du mit streaming.
Vielleicht ist die "Linie" der terminator ist nicht das, was es sein sollte? Wenn die Linien sind nicht beendet mit \r UND \n die internen Funktionen würde vermutlich immer noch Lesen Sie die komplette Datei in den Speicher, würden Sie nicht?
Ich bin mir nicht sicher, warum Sie erhielt eine Fehlermeldung, die in deinem 2. code-Auszug, wenn Sie nicht aufrufen
_lines.Add(line)
, haben Sie vielleicht ein problem an anderer Stelle? Der line terminator ist wahrscheinlich nicht im Zusammenhang mit dem problem - 500 MB zusammenhängenden Speicher wird schwierig sein, zu erhalten in jedem Szenario, es sei denn, Sie sind mit 64-bit und VIEL Speicher.Testen, ob die Zeile-Abschlusszeichen ist das problem dürfte einfach sein. Mach eine Konsole app mit einer einzigen Methode
file.readline(path)
. Wenn es immer noch wirft einen ex, dann eine einzelne "Linie" einfach zu lang ist. Wahrscheinlich, weil intern einen stringbuilder verwendet, die dauerhaft zu erhöhen, Ihre internen array (d.h. Speicherplatz für eine NEUE), ohne dass die GC-Zeit zum Aufräumen.InformationsquelleAutor cjk
Sie zu rechnen haben, die Zeilen zuerst.
Es ist langsamer, aber Lesen Sie bis zu 2.147.483.647 Linien.
InformationsquelleAutor Martin Bächtold