69 Stimmen

Wie lesen eine Datei in eine Folge von Zeilen in F#

Dies ist die C#-Version:

public static IEnumerable<string> ReadLinesEnumerable(string path) {
  using ( var reader = new StreamReader(path) ) {
    var line = reader.ReadLine();
    while ( line != null ) {
      yield return line;
      line = reader.ReadLine();
    }
  }
}

Für die direkte Übersetzung wird jedoch eine veränderbare Variable benötigt.

104voto

Joel Mueller Punkte 27700

Wenn Sie .NET 4.0 verwenden, können Sie einfach File.ReadLines .

> let readLines filePath = System.IO.File.ReadLines(filePath);;

val readLines : string -> seq<string>

77voto

ChaosPandion Punkte 75527
open System.IO

let readLines (filePath:string) = seq {
    use sr = new StreamReader (filePath)
    while not sr.EndOfStream do
        yield sr.ReadLine ()
}

21voto

Tomas Petricek Punkte 233658

Um die Frage zu beantworten, ob es eine Bibliotheksfunktion zur Kapselung dieses Musters gibt - es gibt keine Funktion genau dafür, aber es gibt eine Funktion, mit der Sie eine Sequenz aus einem Zustand namens Seq.unfold . Damit können Sie die obige Funktion wie folgt implementieren:

new StreamReader(filePath) |> Seq.unfold (fun sr -> 
  match sr.ReadLine() with
  | null -> sr.Dispose(); None 
  | str -> Some(str, sr))

Le site sr Wert stellt den Stream-Reader dar und wird als Status übergeben. Solange Sie nicht-null Werte erhalten, können Sie Some mit einem zu erzeugenden Element und dem Status (der sich nach Wunsch ändern kann). Wenn er liest null entsorgen wir es und geben es zurück None um die Sequenz zu beenden. Dies ist kein direktes Äquivalent, weil es nicht ordnungsgemäß entsorgt StreamReader wenn eine Ausnahme ausgelöst wird.

In diesem Fall würde ich auf jeden Fall den Sequenzausdruck verwenden (der in den meisten Fällen eleganter und lesbarer ist), aber es ist nützlich zu wissen, dass er auch mit einer Funktion höherer Ordnung geschrieben werden kann.

15voto

maria Punkte 366
    let lines = File.ReadLines(path)                

    // To check
    lines |> Seq.iter(fun x -> printfn  "%s" x)

5voto

Lars Tackmann Punkte 19195

Auf .NET 2/3 können Sie das tun:

let readLines filePath = File.ReadAllLines(filePath) |> Seq.cast<string>

und auf .NET 4:

let readLines filePath = File.ReadLines(filePath);;

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X