2014-11-10 5 views
5

Ich habe die folgende Textdatei Struktur (die Textdatei ist ziemlich groß, rund 100.000 Zeilen):lesen Zeilen aus großen Textdatei in Swift, bis neue Zeile leer ist: der Swift Weg

A|a1|111|111|111 
B|111|111|111|111 

A|a2|222|222|222 
B|222|222|222|222 
B|222|222|222|222 

A|a3|333|333|333 
B|333|333|333|333 

... 

Ich muss Extrahieren Sie einen Textabschnitt, der sich auf einen bestimmten Schlüssel bezieht. Zum Beispiel, wenn mein Schlüssel A | a2, muss ich die folgenden als String speichern:

A|a2|222|222|222 
B|222|222|222|222 
B|222|222|222|222 

für meine C++ und Objective C Projekte, benutzte ich die getline Funktion C++ wie folgt:

std::ifstream ifs(dataPathStr.c_str()); 

NSString* searchKey = @"A|a2"; 
std::string search_string ([searchKey cStringUsingEncoding:NSUTF8StringEncoding]); 

// read and discard lines from the stream till we get to a line starting with the search_string 
std::string line; 

while(getline(ifs, line) && line.find(search_string) != 0); 

// check if we have found such a line, if not report an error 
if(line.find(search_string) != 0) 
{ 
data = DATA_DEFAULT ; 
} 

else{ 

    // we need to form a string that would include the whole set of data based on the selection 
    dataStr = line + '\n' ; // result initially contains the first line 

    // now keep reading line by line till we get an empty line or eof 
    while(getline(ifs, line) && !line.empty()) 
    { 
     dataStr += line + '\n'; // append this line to the result 
    } 

    data = [NSString stringWithUTF8String:navDataStr.c_str()]; 
} 

Da ich ein Projekt in Swift mache, versuche ich, getline loszuwerden und durch etwas "Cocoaish" zu ersetzen. Aber ich kann keine gute Swift-Lösung finden, um das obige Problem zu lösen. Wenn Sie eine Idee haben, würde ich es sehr schätzen. Vielen Dank!

+0

möglich Duplikat [Lesen Sie eine Datei/URL-Zeile-für-Zeile in Swift] (http: // Stackoverflow. com/questions/24581517/lesen Sie eine Datei-URL-Line-by-Line-in-Swift) –

+0

Interessanter Link, danke. Aber es funktioniert nicht wie angegeben: gibt die vollständige Datenbank zurück und hört nicht bei/n oder/n/r auf. Beste. –

+0

Ich habe es noch einmal getestet: Jeder 'nextLine()' Aufruf gibt eine Zeile aus der Datei als String zurück. Das Standardtrennzeichen ist das Newline-Zeichen ('\ n'). Das Trennzeichen ist nicht in der zurückgegebenen Zeichenfolge enthalten. –

Antwort

9

Verwenden der Klasse Stream von Read a file/URL line-by-line in Swift, könnten Sie tun, dass es Swift wie folgt aus:

let searchKey = "A|a2" 

let bundle = NSBundle.mainBundle() 
let pathNav = bundle.pathForResource("data_apt", ofType: "txt") 
if let aStreamReader = StreamReader(path: pathNav!) { 
    var dataStr = "" 
    while let line = aStreamReader.nextLine() { 
     if line.rangeOfString(searchKey, options: nil, range: nil, locale: nil) != nil { 
      dataStr = line + "\n" 
      break 
     } 
    } 
    if dataStr == "" { 
     dataStr = "DATA_DEFAULT" 
    } else { 
     while let line = aStreamReader.nextLine() { 
      if countElements(line) == 0 { 
       break 
      } 
      dataStr += line + "\n" 
     } 
    } 
    aStreamReader.close() 
    println(dataStr) 
} else { 
    println("cannot open file") 
} 
+2

Martin. Das ist brilliant. Ich danke dir sehr! Ich habe das Problem tatsächlich gefunden. Die Dataset-Textdatei wurde in Windows erstellt und es gab ein Problem mit Zeilenumbrüchen. Ich habe es im Mac mit TextWrangler mit Zeilenumbrüchen Unix (LF) und Viola neu erstellt! Irgendwelche Bedingungen, um Ihren Code in einem kommerziellen Projekt zu verwenden (natürlich zusätzlich zu Ihrem Namen als Copyright im Code)? Ich danke dir sehr! –