2016-11-15 4 views
1

Beachten Sie Folgendes:für Verständnis, Wach- und RandomAccessFile.readLine

Es gibt eine Text-Datei mit einer bestimmten Menge von Linien, wie:

test.txt: a b c d e f g h

(jeweils dort eigene Linie)

Dann gibt es die folgende Klasse für die Analyse verwendet:

class MyAwesomeParser 
{ 
    def parse(fileName: String, readLines: Int): IndexedSeq[String] = 
    { 
     val randomAccessFile = new RandomAccessFile(fileName, "r") 

     val x: IndexedSeq[String] = for 
     { 
      x <- 0 until readLines 
      r = randomAccessFile.readLine() 
     } yield r 

     x 
    } 
} 

Hier kommen die Tests:

class MyAwesomeParserTest extends WordSpec 
{ 
    "MyAwesomeParser" when { 
    "read" should { 
     "parse only specified number of lines" in { 
     val parser = new EdgeParser("") 
     val x = parser.parse("test.txt", 5) 

     assert(x.size == 5) 
     } 
    } 

    "MyAwesomeParser" when { 
    "read" should { 
     "parse only until end of file" in { 
     val parser = new EdgeParser("") 
     val x = parser.parse("test.txt", 10) 

     assert(x.size == 8) 
     } 
    } 
    } 
} 

Zweiter Test liegt das Problem. Jetzt natürlich sagen Sie, sind Sie hier eine Wache fehlt ... na ja, gut, wenn ich

x <- 0 until readLines if randomAccessFile.readLine != null 

zur Umsetzung fügen Sie dann springt es ein paar Zeilen, weil bereits die Linie readline verbraucht.

wird leider nicht funktionieren, da die erste Zeile eine Zuordnung zum Verständnis sein muss.

Nun frage ich mich, ist es überhaupt möglich, mit einem für das Verständnis bis zu einer bestimmten Anzahl von Wiederholungen ODER vor dem readLine != null Zustand zu stoppen?

Ist meine Syntax gerade gebrochen?

Antwort

2

Sie können randomAccessFile.readLine in einem Option, kapseln, so dass null wird None und value zu Some(value) geändert werden.

Außerdem Option kann als eine Sammlung in Betracht gezogen werden, so können Sie es in der gleichen für das Verständnis setzen, wie die IndexedSeq:

for { 
    x <- 0 until readLines 
    r <- Option(randomAccessFile.readLine()) 
} yield r 
3

Wenn Sie Ihre parse Methode bleiben möchten, können Sie einfach getFilePointer verwenden und length

def parse(fileName: String, readLines: Int): IndexedSeq[String] = 
{ 
    val randomAccessFile = new RandomAccessFile(fileName, "r") 

    val x: IndexedSeq[String] = for 
    { 
     x <- 0 until readLines if randomAccessFile.getFilePointer < randomAccessFile.length 
     r = randomAccessFile.readLine() 
    } yield r 

    x 
} 

Doch statt das Rad neu zu erfinden, empfehle ich Ihnen nur scala.io.Source verwenden:

def parse(fileName: String, readLines: Int): Iterator[String] = 
    Source.fromFile(fileName).getLines.take(readLines) 
+0

Ah, Mist ... Ich habe versucht, ein kleines Beispiel zu geben, aber ich will keine Arbeit für mein spezifisches Problem, aber eher eine generische Lösung – Sorona