it-swarm.com.de

Wie lese ich eine bestimmte Zeile in einer Textdatei?

Wie soll ich bei einer Textdatei eine beliebige Zeile und nichts anderes in der Datei lesen?

Sagen wir, ich habe eine Datei test.txt. Wie gehe ich zum Lesen von Zeile 15 in der Datei vor?

Alles, was ich gesehen habe, ist Sachen, bei denen die gesamte Textdatei als String-Array gespeichert wird und dann der Wert der Zeilennummer als Nummer des Strings verwendet wird, der aus dem Array verwendet werden soll, aber es gibt einige Komplikationen: enorm riesig und die Maschine, die die Anwendung, die ich codiere, ist, ist nicht gerade ein erstklassiges System. Geschwindigkeit hat nicht die höchste Priorität, ist aber definitiv ein großes Thema.

Gibt es Möglichkeiten,ONLYeine bestimmte Zeile einer Textdatei zu lesen und das Ergebnis als String zu speichern?

Vielen Dank für Ihre Antworten: Die Datei ist KINDA strukturiert. Es hat 25 Zeilen Info und dann X Zeilen, aber Zeile 17 der ersten 25 hat den Wert X.

Dann gibt es jedoch eine leere Zeile, die sich als zweiter Datensatz in der Datei wiederholt, und X kann für jeden Datensatz einen anderen Wert haben.

Ich möchte die ersten 25 Zeilen als unabhängige Werte lesen und speichern und dann die nächsten X (normalerweise um 250) Zeilen als Array speichern. Dann werde ich es in einer SQL-Datenbank speichern und mit dem NEXT-Datensatz wiederholen, bis ich den Y -ten Datensatz erreicht habe (die Anzahl der Datensätze in der Datei befindet sich in Zeile 3).

EDIT 2 : Okay, ich glaube, ich bin zu einer Lösung gekommen, die auf einer Kombination der Antworten Ihrer Alls basiert.

Ich werde die ersten 25 Zeilen lesen und als Array speichern. Ich kopiere den relevanten Inhalt des Arrays in lokale Variablen und lösche dann die ersten 25 Zeilen. Dann kann ich die Info verwenden, um die nächsten X - Zeilen (den Wert von Element 13 im Array) als Array zu speichern, serialisieren, in einer Datenbank speichern und dann die gerade gelesenen Zeilen löschen.

Ich könnte dann den Vorgang für jeden nachfolgenden Datensatz wiederholen.

Natürlich beruht dies auf einer Annahme, die ich mache. Ehrlich gesagt bin ich mir nicht sicher, ob dies wahr ist. Ist es möglich, die ersten n -Zeilen aus einer Textdatei aus C # zu löschen, ohne das gesamte Objekt lesen und es ohne die ersten n -Zeilen neu schreiben zu müssen?

50
ankushg

.NET 4.0 edit

Seit .NET 4.0 ist es möglich, auf eine einzelne Zeile einer Datei direkt zuzugreifen. Um beispielsweise auf Zeile 15 zuzugreifen:

string line = File.ReadLines(FileName).Skip(14).Take(1).First();

Dadurch wird nur die erforderliche Zeile zurückgegeben


Da Sie den Ort der i-ten Zeile in der Datei nicht vorhersagen können (können Sie?), Müssen Sie auch alle vorherigen Zeilen lesen. Wenn die Zeilennummer klein ist, kann dies effizienter sein als die ReadAllLines-Methode.

string GetLine(string fileName, int line)
{
   using (var sr = new StreamReader(fileName)) {
       for (int i = 1; i < line; i++)
          sr.ReadLine();
       return sr.ReadLine();
   }
}
91
Mehrdad Afshari

Wenn jede Zeile eine feste Länge hat, können Sie einen Stream um sie herum öffnen, (Bytes pro Zeile) * n in die Datei suchen und Ihre Zeile von dort lesen. 

using( Stream stream = File.Open(fileName, FileMode.Open) )
{
    stream.Seek(bytesPerLine * (myLine - 1), SeekOrigin.Begin);
    using( StreamReader reader = new StreamReader(stream) )
    {
        string line = reader.ReadLine();
    }
}

Alternativ können Sie den StreamReader auch verwenden, um Zeilen zu lesen, bis Sie die gewünschte gefunden haben. Dieser Weg ist langsamer, aber immer noch eine Verbesserung gegenüber dem Lesen jeder einzelnen Zeile.

using( Stream stream = File.Open(fileName, FileMode.Open) )
{
    using( StreamReader reader = new StreamReader(fileStream) )
    {
        string line = null;
        for( int i = 0; i < myLineNumber; ++i )
        {
            line = reader.ReadLine();
        }
    }
}
12
Dave Downs

Nein, leider nicht. Auf der Rohebene arbeiten Dateien nicht auf Zeilennummernbasis. Sie arbeiten stattdessen auf Positions-/Versatzbasis. Das Root-Dateisystem hat kein Linienkonzept. Es ist ein Konzept, das durch Komponenten höherer Ebene hinzugefügt wird.

Es gibt also keine Möglichkeit, das Betriebssystem mitzuteilen. Öffnen Sie die Datei in der Zeile blah. Stattdessen müssen Sie die Datei öffnen und neue Zeilen zählen, bis Sie die angegebene Anzahl überschritten haben. Speichern Sie dann die nächsten Bytes in einem Array, bis Sie zur nächsten neuen Zeile gelangen. 

4
JaredPar

Wenn Sie keine Zeilen mit fester Größe haben, müssen Sie jede Zeile lesen, bis Sie die gewünschte Zeile erreichen. Obwohl Sie nicht jede Zeile speichern müssen, löschen Sie sie einfach, wenn es nicht die gewünschte Zeile ist.

Bearbeiten:

Wie bereits erwähnt, ist es auch möglich, in der Datei zu suchen, wenn die Zeilenlängen vorhersagbar sind. Das heißt, Sie können eine deterministische Funktion anwenden, um eine Zeilennummer in eine Dateiposition zu transformieren.

3
Ron Warholic

Wie Mehrdad sagte, können Sie nicht einfach die n-te Zeile suchen, ohne die Datei zu lesen. Sie müssen jedoch nicht die gesamte Datei im Arbeitsspeicher speichern - verwerfen Sie einfach die nicht benötigten Daten.

string line;
using (StreamReader sr = new StreamReader(path))
    for (int i = 0; i<15; i++)
    {
       line = sr.ReadLine();
       if (line==null) break; // there are less than 15 lines in the file
    }
2
VladV

LESEN SIE FÜNF LINIEN EINE ZEIT, setzen Sie Ihre Aussage einfach in if-Anweisung ein, das ist es 

        String str1 = @"C:\Users\TEMP\Desktop\StaN.txt";   

        System.IO.StreamReader file = new System.IO.StreamReader(str1);

        line = file.ReadLine();

        Int32 ctn=0;

        try
        {

            while ((line = file.ReadLine()) != null)
            {

                    if (Counter == ctn)
                    {
                        MessageBox.Show("I am here");
                        ctn=ctn+5;
                        continue;
                    }
                    else
                    {
                        Counter++;
                        //MessageBox.Show(Counter.ToString());
                        MessageBox.Show(line.ToString());
                    } 
                }

            file.Close();
        }
        catch (Exception er)
        {

        }

Wenn die Zeilen alle eine feste Länge haben, können Sie die Suchmethode eines Streams verwenden, um zur korrekten Startposition zu gelangen. 

Wenn die Zeilen eine variable Länge haben, sind Ihre Optionen eingeschränkter. 

Wenn dies eine Datei ist, die Sie nur einmal verwenden und dann verwerfen, lesen Sie sie am besten ein und arbeiten mit ihr im Speicher.

Wenn dies eine Datei ist, in der Sie mehr lesen als schreiben, können Sie eine benutzerdefinierte Indexdatei erstellen, die die Startpositionen jeder Zeile enthält. Verwenden Sie dann diesen Index, um Ihre Suchposition zu erhalten. Das Erstellen der Indexdatei ist ressourcenintensiv. Jedes Mal, wenn Sie der Datei eine neue Zeile hinzufügen, müssen Sie den Index aktualisieren, sodass die Wartung zu einem nicht unbedeutenden Problem wird.

1
RB Davidson

Ausprobiert und getestet. Es ist so einfach wie folgt:

string line = File.ReadLines(filePath).ElementAt(actualLineNumber - 1);

Solange Sie über eine Textdatei verfügen, sollte dies funktionieren. Später können Sie die Zeichenfolge entsprechend den zu lesenden Daten umwandeln und verwenden.

0
Karan Randhawa

Eine Variation. Gibt einen Fehler aus, wenn die Zeilennummer größer als die Anzahl der Zeilen ist.

string GetLine(string fileName, int lineNum)
{
    using (StreamReader sr = new StreamReader(fileName))
    {
        string line;
        int count = 1;
        while ((line = sr.ReadLine()) != null)
        {
            if(count == lineNum)
            {
                return line;
            }
            count++;
        }
    }
    return "line number is bigger than number of lines";  
}
0
paparazzo

Sie können zwar eine N-te Zeile nicht direkt in einer nicht symmetrischen Datei suchen, ohne Daten in der Datei zu lesen (da Sie zählen müssen, wie viele Zeilen Sie in die Datei eingefügt haben), können Sie Zeilenumbrüche zählen, bis Sie die Zeile, die Sie benötigen, die den geringsten Speicherplatz beansprucht und wahrscheinlich die beste Leistung aufweist.

Dies ist speichereffizienter als das Lesen eines ganzen Arrays, da nur die Datei gelesen wird, bis sie das Ende der Datei oder die Zeilennummer erreicht (je nachdem, was zuerst eintritt). Es ist alles andere als perfekt, wird aber wahrscheinlich Ihren Bedürfnissen entsprechen:

string line15 = ReadLine(@"C:\File.csv", 15);

public string ReadLine(string FilePath, int LineNumber){
    string result = "";
    try{
    if( File.Exists(FilePath) ){
        using (StreamReader _StreamReader = new StreamReader(FilePath)){
        for (int a = 0; a < LineNumber; a++) {
            result = _StreamReader.ReadLine();
        }
        }
    }
    }catch{}
    return result;
}
0
Dave

Wenn Ihre Datei Zeilen mit unterschiedlichen Längen enthält und Sie Zeilen häufig lesen müssen und diese schnell lesen müssen, können Sie einen Index der Datei erstellen, indem Sie sie einmal lesen, die Position jeder neuen Zeile speichern und dann eine Zeile lesen Sie suchen nur nach der Position der Zeile in Ihrem Index, suchen dort und lesen dann die Zeile.

Wenn Sie der Datei neue Zeilen hinzufügen, können Sie einfach den Index der neuen Zeilen hinzufügen und müssen nicht alles neu indizieren. Wenn sich Ihre Datei irgendwo in einer Zeile ändert, die Sie bereits indiziert haben, müssen Sie sie erneut indizieren. 

0
user175779

Sie könnten Zeile für Zeile lesen, so dass Sie nicht alles auf einmal lesen müssen (wahrscheinlich überhaupt).

int i=0
while(!stream.eof() && i!=lineNum)
    stream.readLine()
    i++
line = stream.readLine()
0
Samuel