Lire et écrire une chaîne à partir d'un fichier texte

298

J'ai besoin de lire et d'écrire des données vers / depuis un fichier texte, mais je n'ai pas réussi à comprendre comment.

J'ai trouvé cet exemple de code dans l'iBook du Swift, mais je ne sais toujours pas comment écrire ou lire des données.

import Cocoa

class DataImporter
{
    /*
    DataImporter is a class to import data from an external file.
    The class is assumed to take a non-trivial amount of time to initialize.
    */
    var fileName = "data.txt"
    // the DataImporter class would provide data importing functionality here
}

class DataManager
{
    @lazy var importer = DataImporter()
    var data = String[]()
    // the DataManager class would provide data management functionality here
}

let manager = DataManager()
manager.data += "Some data"
manager.data += "Some more data"
// the DataImporter instance for the importer property has not yet been created”

println(manager.importer.fileName)
// the DataImporter instance for the importer property has now been created
// prints "data.txt”



var str = "Hello World in Swift Language."
Jorge Vega Sánchez
la source

Réponses:

548

Pour la lecture et l'écriture, vous devez utiliser un emplacement accessible en écriture, par exemple le répertoire des documents. Le code suivant montre comment lire et écrire une chaîne simple. Vous pouvez le tester sur une aire de jeux.

Swift 3.x - 5.x

let file = "file.txt" //this is the file. we will write to and read from it

let text = "some text" //just a text

if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {

    let fileURL = dir.appendingPathComponent(file)

    //writing
    do {
        try text.write(to: fileURL, atomically: false, encoding: .utf8)
    }
    catch {/* error handling here */}

    //reading
    do {
        let text2 = try String(contentsOf: fileURL, encoding: .utf8)
    }
    catch {/* error handling here */}
}

Swift 2.2

let file = "file.txt" //this is the file. we will write to and read from it

let text = "some text" //just a text

if let dir = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.AllDomainsMask, true).first {
    let path = NSURL(fileURLWithPath: dir).URLByAppendingPathComponent(file)

    //writing
    do {
        try text.writeToURL(path, atomically: false, encoding: NSUTF8StringEncoding)
    }
    catch {/* error handling here */}

    //reading
    do {
        let text2 = try NSString(contentsOfURL: path, encoding: NSUTF8StringEncoding)
    }
    catch {/* error handling here */}
}

Swift 1.x

let file = "file.txt"

if let dirs : [String] = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.AllDomainsMask, true) as? [String] {
    let dir = dirs[0] //documents directory
    let path = dir.stringByAppendingPathComponent(file);
    let text = "some text"

    //writing
    text.writeToFile(path, atomically: false, encoding: NSUTF8StringEncoding, error: nil);

    //reading
    let text2 = String(contentsOfFile: path, encoding: NSUTF8StringEncoding, error: nil)
}
Adam
la source
2
let text2 = String.stringWithContentsOfFile (path) // XCode 6.0
Matt Frear
L'utilisation de cette solution fonctionne, mais si j'ouvre le fichier, il n'y a pas de texte. Suis-je en train de manquer quelque chose?
Nuno Gonçalves
@Adam Quel est ce fichier à let path = dir.stringByAppendingPathComponent (file) ;?
zbz.lvlv
7
Cela devrait être supprimé, le code ne fonctionne pas pour les nouvelles versions de Swift.
1
@ billy_b29 Le code après cette ligne: //readingfait exactement cela.
Adam
88

En supposant que vous avez déplacé votre fichier texte data.txtvers votre projet Xcode (utilisez drag'n'drop et cochez "Copier les fichiers si nécessaire"), vous pouvez effectuer les opérations suivantes, tout comme dans Objective-C:

let bundle = NSBundle.mainBundle()
let path = bundle.pathForResource("data", ofType: "txt")        
let content = NSString.stringWithContentsOfFile(path) as String

println(content) // prints the content of data.txt

Mise à jour:
pour lire un fichier depuis Bundle (iOS), vous pouvez utiliser:

let path = NSBundle.mainBundle().pathForResource("FileName", ofType: "txt")
var text = String(contentsOfFile: path!, encoding: NSUTF8StringEncoding, error: nil)!
println(text)

Mise à jour pour Swift 3:

let path = Bundle.main.path(forResource: "data", ofType: "txt") // file path for file "data.txt"
var text = String(contentsOfFile: path!, encoding: NSUTF8StringEncoding, error: nil)!

Pour Swift 5

let path = Bundle.main.path(forResource: "ListAlertJson", ofType: "txt") // file path for file "data.txt"
let string = try String(contentsOfFile: path!, encoding: String.Encoding.utf8)
wottpal
la source
3
Pour les projets iOS, "stringWithContentsOfFile" n'est pas disponible (obsolète à partir d'iOS 7)
alttag
1
Rien à voir avec les projets iOS, il est obsolète et ne fonctionne plus avec Xcode 6.1 (y compris Mac OS X)
Leo Dabus
1
vous pouvez utiliser String (contentsOfFile: ...)
shim
1
bundle d'utilisation de solution similaire avec iOS 10 Swift 3 ici
Timeless
69

Xcode 8.x • Swift 3.x ou version ultérieure

do {
    // get the documents folder url
    if let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
        // create the destination url for the text file to be saved
        let fileURL = documentDirectory.appendingPathComponent("file.txt")
        // define the string/text to be saved
        let text = "Hello World !!!"
        // writing to disk 
        // Note: if you set atomically to true it will overwrite the file if it exists without a warning
        try text.write(to: fileURL, atomically: false, encoding: .utf8)
        print("saving was successful")
        // any posterior code goes here
        // reading from disk
        let savedText = try String(contentsOf: fileURL)
        print("savedText:", savedText)   // "Hello World !!!\n"
    }
} catch {
    print("error:", error)
}
Leo Dabus
la source
Quelles sont les erreurs les plus courantes de "Il n'y a pas un tel fichier." Parce que j'ai ajouté mes fichiers .txt au navigateur de projet et que j'essaie de les ouvrir, je reçois ce message. (Créez-les sur le bureau et faites-les glisser vers le navigateur de projet)
Darvydas
56

Nouvelle méthode plus simple et recommandée: Apple recommande d'utiliser des URL pour le traitement des fichiers et les autres solutions semblent ici obsolètes (voir les commentaires ci-dessous). Ce qui suit est la nouvelle façon simple de lire et d'écrire avec les URL (n'oubliez pas de gérer les erreurs d'URL possibles):

Swift 5+, 4 et 3.1

import Foundation  // Needed for those pasting into Playground

let fileName = "Test"
let dir = try? FileManager.default.url(for: .documentDirectory, 
      in: .userDomainMask, appropriateFor: nil, create: true)

// If the directory was found, we write a file to it and read it back
if let fileURL = dir?.appendingPathComponent(fileName).appendingPathExtension("txt") {

    // Write to the file named Test
    let outString = "Write this text to the file"
    do {
        try outString.write(to: fileURL, atomically: true, encoding: .utf8)
    } catch {
        print("Failed writing to URL: \(fileURL), Error: " + error.localizedDescription)
    }

    // Then reading it back from the file
    var inString = ""
    do {
        inString = try String(contentsOf: fileURL)
    } catch {
        print("Failed reading from URL: \(fileURL), Error: " + error.localizedDescription)
    }
    print("Read from the file: \(inString)")
}
Sverrisson
la source
1
Pouvez-vous fournir une référence où Apple recommande une telle façon. Ou pouvez-vous expliquer un peu plus pourquoi est-ce la méthode recommandée?
Andrej
6
@Andrej "Les objets URL sont le moyen préféré de faire référence aux fichiers locaux. La plupart des objets qui lisent ou écrivent des données dans un fichier ont des méthodes qui acceptent un objet NSURL au lieu d'un nom de chemin comme référence de fichier." developer.apple.com/library/ios/documentation/Cocoa/Reference/…
Sverrisson
1
Vous n'avez pas besoin de transtyper les erreurs en NSError, ni même d'utiliser "catch let error". Vous pouvez simplement faire un catch et vous obtenez la variable d'erreur gratuitement.
cuomo456
@ cuomo456 votre droite, je le supprime, c'est un reste de la précédente bêta de Swift.
Sverrisson
1
@Alshcompiler Le create: true informe FileManager de créer le répertoire s'il n'est pas déjà là, au lieu d'échouer
Sverrisson
28

Xcode 8, Swift 3 façons de lire le fichier à partir du bundle d'application:

if let path = Bundle.main.path(forResource: filename, ofType: nil) {
    do {
        let text = try String(contentsOfFile: path, encoding: String.Encoding.utf8)
        print(text)
    } catch {
        printError("Failed to read text from \(filename)")
    }
} else {
    printError("Failed to load file from app bundle \(filename)")
} 

Voici une extension pratique de copier-coller

public extension String {
    func contentsOrBlank()->String {
        if let path = Bundle.main.path(forResource:self , ofType: nil) {
            do {
                let text = try String(contentsOfFile:path, encoding: String.Encoding.utf8)
                return text
                } catch { print("Failed to read text from bundle file \(self)") }
        } else { print("Failed to load file from bundle \(self)") }
        return ""
    }
    }

Par exemple

let t = "yourFile.txt".contentsOrBlank()

Vous voulez presque toujours un tableau de lignes:

let r:[String] = "yourFile.txt"
     .contentsOrBlank()
     .characters
     .split(separator: "\n", omittingEmptySubsequences:ignore)
     .map(String.init)
Crashalot
la source
2
J'ai collé dans une extension pratique @crashalot - n'hésitez pas à supprimer, applaudissements
Fattie
1
@Alshcompiler NO! Vous ne pouvez pas ÉCRIRE un fichier dans le bundle.
Sverrisson
Je parlais de lire à partir d'un fichier, c'est la seule réponse qui a fonctionné avec moi si le fichier est dans des fichiers de projet
compilateur Alsh
10

Je veux vous montrer seulement la première partie, qui est lue . Voici comment lire simplement:

Swift 3:

let s = try String(contentsOfFile: Bundle.main.path(forResource: "myFile", ofType: "txt")!)

Swift 2:

let s = try! String(contentsOfFile: NSBundle.mainBundle().pathForResource("myFile", ofType: "txt")!)
AKM Tariqul Islam
la source
5

Manière la plus simple de lire un fichier dans Swift> 4.0

 let path = Bundle.main.path(forResource: "data", ofType: "txt") // file path for file "data.txt"
        do {
            var text = try String(contentsOfFile: path!)
        }
        catch(_){print("error")}
    }
iosMentalist
la source
3

La réponse acceptée ci-dessus d'Adam avait quelques erreurs pour moi, mais voici comment j'ai retravaillé sa réponse et fait en sorte que cela fonctionne pour moi.

let file = "file.txt"

let dirs: [String]? = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.AllDomainsMask, true) as? [String]

if (dirs != nil) {
    let directories:[String] = dirs!
    let dirs = directories[0]; //documents directory
    let path = dirs.stringByAppendingPathComponent(file);
    let text = "some text"

    //writing
    text.writeToFile(path, atomically: false, encoding: NSUTF8StringEncoding, error: nil);

    //reading
     var error:NSError?

    //reading
    let text2 = String(contentsOfFile: path, encoding:NSUTF8StringEncoding, error: &error)

    if let theError = error {
        print("\(theError.localizedDescription)")
    }
}
DCorrigan
la source
3

Vous pouvez trouver cet outil utile non seulement pour lire à partir d'un fichier dans Swift, mais également pour analyser votre entrée: https://github.com/shoumikhin/StreamScanner

Spécifiez simplement le chemin du fichier et les délimiteurs de données comme ceci:

import StreamScanner

if let input = NSFileHandle(forReadingAtPath: "/file/path")
{
    let scanner = StreamScanner(source: input, delimiters: NSCharacterSet(charactersInString: ":\n"))  //separate data by colons and newlines

    while let field: String = scanner.read()
    {
        //use field
    }
}

J'espère que cela t'aides.

shoumikhin
la source
2

J'ai dû recoder comme ceci:

let path = NSBundle.mainBundle().pathForResource("Output_5", ofType: "xml")
let text = try? NSString(contentsOfFile: path! as String, encoding: NSUTF8StringEncoding)
print(text)
Nagarjun
la source
2

Dans l'exemple de fonction, (lecture | écriture) DocumentsFromFile (...) ayant certains wrappers de fonction semble certainement logique puisque tout dans OSx et iOS semble avoir besoin de trois ou quatre classes principales instanciées et d'un tas de propriétés, configurées, liées, instancié et défini, juste pour écrire "Salut" dans un fichier, dans 182 pays.

Cependant, ces exemples ne sont pas suffisamment complets pour être utilisés dans un vrai programme. La fonction d'écriture ne signale aucune erreur lors de la création ou de l'écriture dans le fichier. À la lecture, je ne pense pas que ce soit une bonne idée de renvoyer une erreur indiquant que le fichier n'existe pas en tant que chaîne censée contenir les données lues. Vous voudriez savoir qu'il a échoué et pourquoi, à travers un mécanisme de notification, comme une exception. Ensuite, vous pouvez écrire du code qui renvoie quel est le problème et permet à l'utilisateur de le corriger, ou "correctement" interrompt le programme à ce stade.

Vous ne voudriez pas simplement renvoyer une chaîne contenant un «fichier d'erreur n'existe pas». Ensuite, vous devrez rechercher l'erreur dans la chaîne de l'appel de fonction à chaque fois et la gérer. Vous ne pouvez également pas vraiment savoir si la chaîne d'erreur a été réellement lue à partir d'un fichier réel ou si elle a été produite à partir de votre code.

Vous ne pouvez même pas appeler la lecture comme ceci dans swift 2.2 et Xcode 7.3 car NSString (contentsOfFile ...) lève une exception. Il s'agit d'une erreur de compilation si vous n'avez pas de code pour l'attraper et faire quelque chose avec, comme l'imprimer sur stdout, ou mieux, une fenêtre contextuelle d'erreur ou stderr. J'ai entendu dire qu'Apple s'éloignait des tentatives de capture et des exceptions, mais cela va être long et il n'est pas possible d'écrire du code sans cela. Je ne sais pas d'où vient l'argument & error, peut-être une version plus ancienne, mais NSString.writeTo [File | URL] n'a pas actuellement d'argument NSError. Ils sont définis comme ceci dans NSString.h:

public func writeToURL(url: NSURL, atomically useAuxiliaryFile: Bool, encoding enc: UInt) throws
public func writeToFile(path: String, atomically useAuxiliaryFile: Bool, encoding enc: UInt) throws
public convenience init(contentsOfURL url: NSURL, encoding enc: UInt) throws
public convenience init(contentsOfFile path: String, encoding enc: UInt) throws

En outre, le fichier inexistant n'est que l'un des nombreux problèmes potentiels que votre programme pourrait rencontrer lors de la lecture d'un fichier, tels qu'un problème d'autorisations, la taille du fichier ou de nombreux autres problèmes pour lesquels vous ne voudriez même pas essayer de coder un gestionnaire pour chacun d'entre eux. Il vaut mieux supposer que tout est correct et attraper et imprimer, ou gérer, une exception si quelque chose ne va pas, d'ailleurs, à ce stade, vous n'avez pas vraiment le choix de toute façon.

Voici mes réécritures:

func writeToDocumentsFile(fileName:String,value:String) {

    let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString!
    let path = documentsPath.stringByAppendingPathComponent(fileName)

    do {
        try value.writeToFile(path, atomically: true, encoding: NSUTF8StringEncoding)
    } catch let error as NSError {
        print("ERROR : writing to file \(path) : \(error.localizedDescription)")
    }

}

func readFromDocumentsFile(fileName:String) -> String {

    let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
    let path = documentsPath.stringByAppendingPathComponent(fileName)

    var readText : String = ""

    do {
        try readText = NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding) as String
    }
    catch let error as NSError {
        print("ERROR : reading from file \(fileName) : \(error.localizedDescription)")
    }
    return readText
}
Sam Allen
la source
Dans beaucoup de vos réponses, je pense que vous ne comprenez pas mon point. (ou vous pouvez ne pas vous en soucier et c'est ok). Cependant, pour être clair, lever une exception et la gérer d'une manière ou d'une autre lorsque vous recherchez un fichier qui n'est pas là (ou a un autre problème tel qu'une autorisation) est bien mieux que de renvoyer une chaîne telle que "ERREUR: Fichier [nom de fichier] n'existe pas "car la chaîne que vous étiez censé lire dans le fichier. Ensuite, il suffit d'imprimer cela. Si quelque chose vous devez imprimer les détails de l'exception, pas la chaîne qui n'a pas pu être lue qui contient maintenant une erreur. Le programme ne devrait probablement pas simplement continuer.
Sam Allen du
2

Pour mon fichier txt fonctionne de cette façon:

let myFileURL = NSBundle.mainBundle().URLForResource("listacomuni", withExtension: "txt")!
let myText = try! String(contentsOfURL: myFileURL, encoding: NSISOLatin1StringEncoding)
print(String(myText))
Alessandro Mattiuzzi
la source
2

Pour éviter toute confusion et ajouter de la facilité, j'ai créé deux fonctions pour lire et écrire des chaînes dans des fichiers du répertoire des documents. Voici les fonctions:

func writeToDocumentsFile(fileName:String,value:String) {
    let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as! NSString
    let path = documentsPath.stringByAppendingPathComponent(fileName)
    var error:NSError?
    value.writeToFile(path, atomically: true, encoding: NSUTF8StringEncoding, error: &error)
}

func readFromDocumentsFile(fileName:String) -> String {
    let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as! NSString
    let path = documentsPath.stringByAppendingPathComponent(fileName)
    var checkValidation = NSFileManager.defaultManager()
    var error:NSError?
    var file:String

    if checkValidation.fileExistsAtPath(path) {
        file = NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding, error: nil) as! String
    } else {
        file = "*ERROR* \(fileName) does not exist."
    }

    return file
}

Voici un exemple de leur utilisation:

writeToDocumentsFile("MyText.txt","Hello world!")

let value = readFromDocumentsFile("MyText.txt")
println(value)  //Would output 'Hello world!'

let otherValue = readFromDocumentsFile("SomeText.txt")
println(otherValue)  //Would output '*ERROR* SomeText.txt does not exist.'

J'espère que cela t'aides!

Version Xcode: 6.3.2

gooroo7
la source
2

Dernier code swift3
Vous pouvez lire les données d'un fichier texte en utilisant simplement le code ci-dessous Ce fichier texte

     {
"NumberOfSlices": "8",
"NrScenes": "5",
"Scenes": [{
           "dataType": "label1",
           "image":"http://is3.mzstatic.com/image/thumb/Purple19/v4/6e/81/31/6e8131cf-2092-3cd3-534c-28e129897ca9/mzl.syvaewyp.png/53x53bb-85.png",

           "value": "Hello",
           "color": "(UIColor.red)"
           }, {
           "dataType": "label2",
           "image":"http://is1.mzstatic.com/image/thumb/Purple71/v4/6c/4c/c1/6c4cc1bc-8f94-7b13-f3aa-84c41443caf3/mzl.hcqvmrix.png/53x53bb-85.png",
           "value": "Hi There",
           "color": "(UIColor.blue)"
           }, {
           "dataType": "label3",
           "image":"http://is1.mzstatic.com/image/thumb/Purple71/v4/6c/4c/c1/6c4cc1bc-8f94-7b13-f3aa-84c41443caf3/mzl.hcqvmrix.png/53x53bb-85.png",

           "value": "hi how r u ",
           "color": "(UIColor.green)"
           }, {
           "dataType": "label4",
           "image":"http://is1.mzstatic.com/image/thumb/Purple71/v4/6c/4c/c1/6c4cc1bc-8f94-7b13-f3aa-84c41443caf3/mzl.hcqvmrix.png/53x53bb-85.png",
           "value": "what are u doing  ",
           "color": "(UIColor.purple)"
           }, {
           "dataType": "label5",
          "image":"http://is1.mzstatic.com/image/thumb/Purple71/v4/6c/4c/c1/6c4cc1bc-8f94-7b13-f3aa-84c41443caf3/mzl.hcqvmrix.png/53x53bb-85.png",
           "value": "how many times ",
           "color": "(UIColor.white)"
           }, {
           "dataType": "label6",
           "image":"http://is1.mzstatic.com/image/thumb/Purple71/v4/5a/f3/06/5af306b0-7cac-1808-f440-bab7a0d18ec0/mzl.towjvmpm.png/53x53bb-85.png",
           "value": "hi how r u ",
           "color": "(UIColor.blue)"
           }, {
           "dataType": "label7",
           "image":"http://is5.mzstatic.com/image/thumb/Purple71/v4/a8/dc/eb/a8dceb29-6daf-ca0f-d037-df9f34cdc476/mzl.ukhhsxik.png/53x53bb-85.png",
           "value": "hi how r u ",
           "color": "(UIColor.gry)"
           }, {
           "dataType": "label8",
           "image":"http://is2.mzstatic.com/image/thumb/Purple71/v4/15/23/e0/1523e03c-fff2-291e-80a7-73f35d45c7e5/mzl.zejcvahm.png/53x53bb-85.png",
           "value": "hi how r u ",
           "color": "(UIColor.brown)"
           }]

}

Vous pouvez utiliser ce code pour obtenir des données du fichier texte json dans swift3

     let filePath = Bundle.main.path(forResource: "nameoftheyourjsonTextfile", ofType: "json")


    let contentData = FileManager.default.contents(atPath: filePath!)
    let content = NSString(data: contentData!, encoding: String.Encoding.utf8.rawValue) as? String

    print(content)
    let json = try! JSONSerialization.jsonObject(with: contentData!) as! NSDictionary
    print(json)
    let app = json.object(forKey: "Scenes") as! NSArray!
    let _ : NSDictionary
    for dict in app! {
        let colorNam = (dict as AnyObject).object(forKey: "color") as! String
        print("colors are \(colorNam)")

       // let colour = UIColor(hexString: colorNam) {
       // colorsArray.append(colour.cgColor)
       // colorsArray.append(colorNam  as! UIColor)

        let value = (dict as AnyObject).object(forKey: "value") as! String
        print("the values are \(value)")
        valuesArray.append(value)

        let images = (dict as AnyObject).object(forKey: "image") as! String
        let url = URL(string: images as String)
        let data = try? Data(contentsOf: url!)
        print(data)
        let image1 = UIImage(data: data!)! as UIImage
        imagesArray.append(image1)
         print(image1)
            }
Gangireddy Rami Reddy
la source
2

Cela fonctionne avec Swift 3.1.1 sous Linux:

import Foundation

let s = try! String(contentsOfFile: "yo", encoding: .utf8)
Adam Dingle
la source
1

écrire dans ViewDidLoad

var error: NSError?
var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
var documentsDirectory = paths.first as String
var dataPath = documentsDirectory.stringByAppendingPathComponent("MyFolder")

if !NSFileManager.defaultManager().fileExistsAtPath(dataPath) {
    NSFileManager.defaultManager().createDirectoryAtPath(dataPath, withIntermediateDirectories: false, attributes: nil, error: &error)
} else {
    println("not creted or exist")
}

func listDocumentDirectoryfiles() -> [String] {
    if let documentDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first as? String {
        let myFilePath = documentDirectory.stringByAppendingPathComponent("MyFolder")
        return NSFileManager.defaultManager().contentsOfDirectoryAtPath(myFilePath, error: nil) as [String]
    }
    return []
}
NRV
la source
1

Les solutions antérieures répondent à la question, mais dans mon cas, la suppression de l'ancien contenu du fichier lors de l'écriture était un problème.

J'ai donc créé un morceau de code pour écrire dans un fichier dans le répertoire des documents sans supprimer le contenu précédent. Vous avez probablement besoin d'une meilleure gestion des erreurs, mais je pense que c'est un bon point de départ. Swift 4. Utilisation:

    let filename = "test.txt"
    createOrOverwriteEmptyFileInDocuments(filename: filename)
    if let handle = getHandleForFileInDocuments(filename: filename) {
        writeString(string: "aaa", fileHandle: handle)
        writeString(string: "bbb", fileHandle: handle)
        writeString(string: "\n", fileHandle: handle)
        writeString(string: "ccc", fileHandle: handle)
    }

Méthodes d'assistance:

func createOrOverwriteEmptyFileInDocuments(filename: String){
    guard let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
        debugPrint("ERROR IN createOrOverwriteEmptyFileInDocuments")
        return
    }
    let fileURL = dir.appendingPathComponent(filename)
    do {
        try "".write(to: fileURL, atomically: true, encoding: .utf8)
    }
    catch {
        debugPrint("ERROR WRITING STRING: " + error.localizedDescription)
    }
    debugPrint("FILE CREATED: " + fileURL.absoluteString)
}

private func writeString(string: String, fileHandle: FileHandle){
    let data = string.data(using: String.Encoding.utf8)
    guard let dataU = data else {
        debugPrint("ERROR WRITING STRING: " + string)
        return
    }
    fileHandle.seekToEndOfFile()
    fileHandle.write(dataU)
}

private func getHandleForFileInDocuments(filename: String)->FileHandle?{
    guard let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
        debugPrint("ERROR OPENING FILE")
        return nil
    }
    let fileURL = dir.appendingPathComponent(filename)
    do {
        let fileHandle: FileHandle? = try FileHandle(forWritingTo: fileURL)
        return fileHandle
    }
    catch {
        debugPrint("ERROR OPENING FILE: " + error.localizedDescription)
        return nil
    }
}
Szuwar_Jr
la source
1

Swift 3.x - 5.x

Le meilleur exemple est de créer un local Logfileavec une extension .txt qui peut être visible et affichée "Files App"avec la date et l'heure actuelles comme nom de fichier

il suffit d'ajouter ce code dans info.plist activer ces deux fonctionnalités

  UIFileSharingEnabled
  LSSupportsOpeningDocumentsInPlace

et cette fonction ci-dessous

var logfileName : String = ""
func getTodayString() -> String{

    let date = Date()
    let calender = Calendar.current
    let components = calender.dateComponents([.year,.month,.day,.hour,.minute,.second], from: date)

    let year = components.year
    let month = components.month
    let day = components.day
    let hour = components.hour
    let minute = components.minute
    let second = components.second

    let today_string = String(year!) + "-" + String(month!) + "-" + String(day!) + "-" + String(hour!)  + "" + String(minute!) + "" +  String(second!)+".txt"

    return today_string

}

func LogCreator(){
    logfileName = getTodayString()

    print("LogCreator: Logfile Generated Named: \(logfileName)")

    let file = logfileName //this is the file. we will write to and read from it

    let text = "some text" //just a text

    if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {

        let fileURL = dir.appendingPathComponent(file)
        let documentPath = NSSearchPathForDirectoriesInDomains(.documentDirectory,.userDomainMask, true)[0]
        print("LogCreator: The Logs are Stored at location \(documentPath)")


        //writing
        do {
            try text.write(to: fileURL, atomically: false, encoding: .utf8)
        }
        catch {/* error handling here */}

        //reading
        do {
            let text2 = try String(contentsOf: fileURL, encoding: .utf8)
            print("LogCreator: The Detail log are :-\(text2)")
        }
        catch {/* error handling here */}
    }
}


  [1]: https://i.stack.imgur.com/4eg12.png
Vishal Shelake
la source
J'ai essayé, mais j'ai dû manquer quelque chose. Il enregistre mon document et le place dans le fichier: /// var / mobile / Containers / Data / Application / E4BF1065-3B48-4E53-AC1D-0DC893CCB498 / Documents / mais je ne le trouve pas dans les fichiers.
user3069232
1
J'ai raté CETTE clé ... <key> CFBundleDisplayName </key> <string> $ {PRODUCT_NAME} </string> a fonctionné dans iOS 13, Swift 5
user3069232
0
 func writeToDocumentsFile(fileName:String,value:String) {
    let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
    let path = documentsPath.appendingPathComponent(fileName)
    do{
    try value.write(toFile: path, atomically: true, encoding: String.Encoding.utf8)
}catch{
    }
    }

func readFromDocumentsFile(fileName:String) -> String {
    let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
    let path = documentsPath.appendingPathComponent(fileName)
    let checkValidation = FileManager.default
    var file:String

    if checkValidation.fileExists(atPath: path) {
        do{
       try file = NSString(contentsOfFile: path, encoding: String.Encoding.utf8.rawValue) as String
        }catch{
            file = ""
        }
        } else {
        file = ""
    }

    return file
}
maroc
la source
0

Xcode 8.3.2 3.x Swift . Utilisation de NSKeyedArchiver et NSKeyedUnarchiver

Lecture de fichiers à partir de documents

let documentsDirectoryPathString = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let documentsDirectoryPath = NSURL(string: documentsDirectoryPathString)!
let jsonFilePath = documentsDirectoryPath.appendingPathComponent("Filename.json")

let fileManager = FileManager.default
var isDirectory: ObjCBool = false

if fileManager.fileExists(atPath: (jsonFilePath?.absoluteString)!, isDirectory: &isDirectory) {

let finalDataDict = NSKeyedUnarchiver.unarchiveObject(withFile: (jsonFilePath?.absoluteString)!) as! [String: Any]
}
else{
     print("File does not exists")
}

Écrire un fichier dans des documents

NSKeyedArchiver.archiveRootObject(finalDataDict, toFile:(jsonFilePath?.absoluteString)!)
Prashant Gaikwad
la source