Bestimmen Sie die Anzahl der Zeilen in einer Textdatei
-
02-07-2019 - |
Frage
Gibt es eine einfache Möglichkeit, programmatisch die Anzahl der Zeilen in einer Textdatei zu bestimmen?
Lösung
Im Ernst verspätetes edit: Wenn Sie .NET 4.0 oder höher
mit Die File
Klasse hat eine neue ReadLines
Methode, die Linien lazily aufzählt anstatt sie alle in einem Array wie ReadAllLines
gierig zu lesen. So, jetzt können Sie sowohl Effizienz und Prägnanz mit haben:
var lineCount = File.ReadLines(@"C:\file.txt").Count();
Original Antwort
Wenn Sie sich auch nicht um Effizienz gestört, können Sie einfach schreiben:
var lineCount = File.ReadAllLines(@"C:\file.txt").Length;
Für eine effizientere Methode könnten Sie tun:
var lineCount = 0;
using (var reader = File.OpenText(@"C:\file.txt"))
{
while (reader.ReadLine() != null)
{
lineCount++;
}
}
Edit: Als Antwort auf Fragen zu Effizienz
Der Grund sagte ich das zweite effizienter war, in Bezug auf die Speichernutzung, die nicht unbedingt beschleunigen. Die erste lädt den gesamten Inhalt der Datei in eine Anordnung, die bedeutet, dass es zumindest so viel Speicher wie die Größe der Datei zuordnen muss. Die zweite Schleife nur eine Zeile zu einer Zeit, so dass es nie zu einem Zeitpunkt mehr als eine Zeile im Wert von Speicher zugewiesen hat. Das ist nicht so wichtig für kleine Dateien, aber für größere Dateien könnte es ein Problem sein (wenn Sie versuchen, die Anzahl der Zeilen in einer 4 GB-Datei auf einem 32-Bit-System, zum Beispiel, wo es einfach nicht genug ist Benutzermodus-Adressraum ein Array diese große) zuzuteilen.
In Bezug auf die Geschwindigkeit erwarte ich würde nicht viel drin sein. Es ist möglich, dass ReadAllLines einige interne Optimierungen, aber auf der anderen Seite kann es haben einen massiven Teil des Speichers zuzuweisen. Ich würde vermuten, dass ReadAllLines könnte für kleine Dateien schneller, aber deutlich langsamer für große Dateien; obwohl der einzige Weg, um es mit einer Stoppuhr oder Code Profiler zu messen wäre zu sagen.
Andere Tipps
Die einfachste:
int lines = File.ReadAllLines("myfile").Length;
Dies würde verwenden weniger Speicher, aber wahrscheinlich länger dauern
int count = 0;
string line;
TextReader reader = new StreamReader("file.txt");
while ((line = reader.ReadLine()) != null)
{
count++;
}
reader.Close();
Wenn durch einfach meinen Sie einen Codezeile, die leicht zu entziffern, aber pro Chance ineffizient?
string[] lines = System.IO.File.RealAllLines($filename);
int cnt = lines.Count();
Das ist wahrscheinlich der schnellste Weg, wie viele Zeilen zu kennen.
Sie könnten auch tun (je nachdem, ob Sie es in puffern)
#for large files
while (...reads into buffer){
string[] lines = Regex.Split(buffer,System.Enviorment.NewLine);
}
Es gibt noch zahlreiche andere Möglichkeiten, aber eine der oben ist wahrscheinlich das, was Sie mit gehen werden.
Sie es schnell in lesen können, und einen Zähler erhöhen, nur eine Schleife verwenden zu erhöhen, nichts mit dem Text zu tun.
die Zeilenumbrüche zählen / Line-Feeds. Ich glaube, in Unicode sie sind immer noch 0x000D und 0x000A sind. auf diese Weise können Sie so effizient oder als ineffizient sein, wie Sie wollen, und entscheiden, ob Sie mit den beiden Zeichen zu tun haben oder nicht
Ein gangbarer Weg, und eine, die ich persönlich in Anspruch genommen haben, wäre eine eigene Kopfzeile der ersten Zeile der Datei hinzuzufügen. Ich tat dies für ein individuelles Modell Format für mein Spiel. Grundsätzlich habe ich ein Tool, das meine OBJ-Dateien optimiert, das Loswerden der Mist brauche ich nicht, wandelt sie in ein besseres Layout und schreibt dann die Gesamtzahl der Zeilen, Gesichter, Normalen, Ecken und Textur UVs auf die erste Zeile. Diese Daten werden dann durch verschiedene Array-Puffer verwendet wird, wenn das Modell geladen wird.
Dies ist auch nützlich, weil man nur einmal eine Schleife durch die Datei benötigt sie in zu laden, statt einmal die Linien zu zählen und die Daten wieder in Ihre erstellten Puffer zu lesen.
Lesen einer Datei an und für sich dauert einige Zeit, Müll das Ergebnis sammeln weiteres Problem ist, wie Sie die gesamte Datei lesen Sie einfach die Newline-Zeichen zu zählen (s),
An einem gewissen Punkt, jemand zu haben, die Zeichen in der Datei zu lesen, unabhängig davon, ob dies der Rahmen oder wenn es Ihr Code. Das heißt, Sie haben die Datei zu öffnen und es in den Speicher geladen, wenn die Datei groß ist dies möglicherweise wird ein Problem sein, da der Speicher Müll gesammelt werden muss.
Nima Ara eine nette Analyse dass Sie
berücksichtigen könntenHier wird die Lösung vorgeschlagen, wie es in einer Zeit, 4 Zeichen liest, zählt die Zeilenvorschub und erneut verwendet die gleiche Speicheradresse wieder für das nächste Zeichen Vergleich.
private const char CR = '\r';
private const char LF = '\n';
private const char NULL = (char)0;
public static long CountLinesMaybe(Stream stream)
{
Ensure.NotNull(stream, nameof(stream));
var lineCount = 0L;
var byteBuffer = new byte[1024 * 1024];
const int BytesAtTheTime = 4;
var detectedEOL = NULL;
var currentChar = NULL;
int bytesRead;
while ((bytesRead = stream.Read(byteBuffer, 0, byteBuffer.Length)) > 0)
{
var i = 0;
for (; i <= bytesRead - BytesAtTheTime; i += BytesAtTheTime)
{
currentChar = (char)byteBuffer[i];
if (detectedEOL != NULL)
{
if (currentChar == detectedEOL) { lineCount++; }
currentChar = (char)byteBuffer[i + 1];
if (currentChar == detectedEOL) { lineCount++; }
currentChar = (char)byteBuffer[i + 2];
if (currentChar == detectedEOL) { lineCount++; }
currentChar = (char)byteBuffer[i + 3];
if (currentChar == detectedEOL) { lineCount++; }
}
else
{
if (currentChar == LF || currentChar == CR)
{
detectedEOL = currentChar;
lineCount++;
}
i -= BytesAtTheTime - 1;
}
}
for (; i < bytesRead; i++)
{
currentChar = (char)byteBuffer[i];
if (detectedEOL != NULL)
{
if (currentChar == detectedEOL) { lineCount++; }
}
else
{
if (currentChar == LF || currentChar == CR)
{
detectedEOL = currentChar;
lineCount++;
}
}
}
}
if (currentChar != LF && currentChar != CR && currentChar != NULL)
{
lineCount++;
}
return lineCount;
}
Vor Ihnen sehen können, dass eine Linie ein Zeichen in einer Zeit von dem zugrunde liegenden Rahmen auch gelesen wird, wie Sie alle Zeichen lesen, müssen Sie den Zeilenvorschub zu sehen.
Wenn Sie es als getan Bucht Nima Profil würden Sie sehen, dass dies eine ziemlich schnelle und effiziente Art und Weise, dies zu tun.
try {
string path = args[0];
FileStream fh = new FileStream(path, FileMode.Open, FileAccess.Read);
int i;
string s = "";
while ((i = fh.ReadByte()) != -1)
s = s + (char)i;
//its for reading number of paragraphs
int count = 0;
for (int j = 0; j < s.Length - 1; j++) {
if (s.Substring(j, 1) == "\n")
count++;
}
Console.WriteLine("The total searches were :" + count);
fh.Close();
} catch(Exception ex) {
Console.WriteLine(ex.Message);
}