web-dev-qa-db-fra.com

Lire un fichier texte ligne par ligne dans Swift?

Je viens de commencer à apprendre Swift, j'ai mon code à lire dans le fichier texte et l'application affiche le contenu du fichier texte entier. Comment afficher ligne par ligne et appeler plusieurs fois cette ligne?

TextFile.txt contient les éléments suivants.

  1. Banane
  2. Apple
  3. poire
  4. fraise
  5. myrtille
  6. cassis

ce qui suit est ce qui a actuellement ..

  if let path = NSBundle.mainBundle().pathForResource("TextFile", ofType: "txt"){
        var data = String(contentsOfFile:path, encoding: NSUTF8StringEncoding, error: nil)
            if let content = (data){
                TextView.text = content
    }

aussi s'il y a une autre façon de le faire, faites-le moi savoir. Très appréciée

40
ScarletEnvy

Swift 3.0

if let path = Bundle.main.path(forResource: "TextFile", ofType: "txt") {
    do {
        let data = try String(contentsOfFile: path, encoding: .utf8)
        let myStrings = data.components(separatedBy: .newlines)
        TextView.text = myStrings.joined(separator: ", ")
    } catch {
        print(error)
    }
}

La variable myStrings doit être chaque ligne des données.

Le code utilisé est de: lecture de fichier ligne par ligne dans iOS SDK écrit en Obj-C et utilisant NSString

Consultez l'historique des modifications pour les versions précédentes de Swift.

83
Caleb

Mise à jour pour Swift 2.0/Xcode 7.2

    do {
        if let path = NSBundle.mainBundle().pathForResource("TextFile", ofType: "txt"){
            let data = try String(contentsOfFile:path, encoding: NSUTF8StringEncoding)

            let myStrings = data.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet())
            print(myStrings)
        }
    } catch let err as NSError {
        //do sth with Error
        print(err)
    }

Il convient également de mentionner que ce code lit un fichier qui se trouve dans le dossier du projet (puisque pathForResource est utilisé), et non par ex. le dossier des documents de l'appareil

4
glace

La façon la plus simple et la plus simple de le faire dans Swift 5.0, serait probablement la suivante:

import Foundation

// Determine the file name
let filename = "main.Swift"

// Read the contents of the specified file
let contents = try! String(contentsOfFile: filename)

// Split the file into separate lines
let lines = contents.split(separator:"\n")

// Iterate over each line and print the line
for line in lines {
    print("\(line)")
}

Remarque: Cela lit le fichier entier en mémoire, puis itère simplement le fichier en mémoire pour produire des lignes ....

Nous remercions: https://wiki.codermerlin.com/mediawiki/index.php/Code_Snippet:_Print_a_File_Line-by-Line

2
NerdOfCode

Ce n'est pas joli, mais je pense que cela fonctionne (sur Swift 5). Cela utilise la commande POSIX getline sous-jacente pour l'itération et la lecture de fichiers.

typealias LineState = (
  // pointer to a C string representing a line
  linePtr:UnsafeMutablePointer<CChar>?,
  linecap:Int,
  filePtr:UnsafeMutablePointer<FILE>?
)

/// Returns a sequence which iterates through all lines of the the file at the URL.
///
/// - Parameter url: file URL of a file to read
/// - Returns: a Sequence which lazily iterates through lines of the file
///
/// - warning: the caller of this function **must** iterate through all lines of the file, since aborting iteration midway will leak memory and a file pointer
/// - precondition: the file must be UTF8-encoded (which includes, ASCII-encoded)
func lines(ofFile url:URL) -> UnfoldSequence<String,LineState>
{
  let initialState:LineState = (linePtr:nil, linecap:0, filePtr:fopen(fileURL.path,"r"))
  return sequence(state: initialState, next: { (state) -> String? in
    if getline(&state.linePtr, &state.linecap, state.filePtr) > 0,
      let theLine = state.linePtr  {
      return String.init(cString:theLine)
    }
    else {
      if let actualLine = state.linePtr  { free(actualLine) }
      fclose(state.filePtr)
      return nil
    }
  })
}

Voici comment vous pourriez l'utiliser:

for line in lines(ofFile:myFileURL) {
  print(line)
}
1
algal

Vous souhaitez probablement lire l'intégralité du fichier en une seule fois. Je parie que c'est très petit.

Mais vous souhaitez ensuite diviser la chaîne résultante en un tableau, puis répartir le contenu du tableau entre les différents éléments de l'interface utilisateur, tels que les cellules du tableau.

Un exemple simple:

    var x: String = "abc\ndef"
    var y = x.componentsSeparatedByString("\n")
    // y is now a [String]: ["abc", "def"]
1
BaseZen