2014-11-10 17 views
5

Ho la seguente struttura di file di testo (il file di testo è abbastanza grande, circa 100.000 linee):leggere le linee da grandi file di testo in Swift fino nuova linea è vuoto: il modo Swift

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 

... 

ho bisogno di estrarre un pezzo di testo relativo a una determinata chiave. Per esempio, se la chiave è A | a2, ho bisogno di salvare quanto segue come una stringa:

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

Per il mio C++ e progetti Objective C, ho usato la funzione getline C++ come segue:

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()]; 
} 

Mentre sto realizzando un progetto in Swift, sto cercando di sbarazzarmi di getline e sostituirlo con qualcosa di "Cocoaish". Ma non riesco a trovare una buona soluzione Swift per risolvere il problema precedente. Se hai un'idea, lo apprezzerei davvero. Grazie!

+0

possibile duplicato di [Leggere un file/URL linea per linea a Swift] (http: // StackOverflow. it/questions/24581517/read-a-file-url-line-by-line-in-swift) –

+0

Link interessante, grazie. Ma non funziona come indicato: restituisce il database completo e non si ferma a/n o/n/r. Migliore. –

+0

L'ho testato ancora una volta: ogni chiamata 'nextLine()' restituisce una riga dal file come una stringa. Il delimitatore predefinito è il carattere di nuova riga ('\ n'). Il delimitatore non è incluso nella stringa restituita. –

risposta

9

Uso della classe StreamReader da Read a file/URL line-by-line in Swift, si potrebbe fare che Swift in questo modo:

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. È brillante. Grazie mille! Ho effettivamente trovato il problema. Il file di testo del set di dati è stato creato in Windows e si è verificato un problema con interruzioni di riga. L'ho ricreato in Mac usando TextWrangler con Line break Unix (LF) e viola! Qualunque condizione per utilizzare il tuo codice in un progetto commerciale (ovviamente oltre a mettere il tuo nome come Copyright nel codice)? Grazie mille! –