Przeczytaj i napisz ciąg z pliku tekstowego

298

Muszę czytać i zapisywać dane do / z pliku tekstowego, ale nie byłem w stanie dowiedzieć się, jak to zrobić.

Znalazłem ten przykładowy kod w iBooku Swift, ale nadal nie wiem, jak zapisywać lub odczytywać dane.

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
źródło

Odpowiedzi:

547

Do czytania i pisania należy używać lokalizacji, w której można zapisywać, na przykład katalogu dokumentów. Poniższy kod pokazuje, jak czytać i pisać prosty ciąg. Możesz to przetestować na placu zabaw.

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
źródło
2
let text2 = String.stringWithContentsOfFile (ścieżka) // XCode 6.0
Matt Frear
Korzystanie z tego rozwiązania działa, ale jeśli otworzę plik, nie będzie w nim tekstu. Czy coś mi brakuje?
Nuno Gonçalves,
@Adam Co to za plik w let path = dir.stringByAppendingPathComponent (plik) ;?
zbz.lvlv
7
Należy to usunąć, kod nie działa dla nowych wersji Swift.
1
@ billy_b29 Kod po tej linii: //readingrobi dokładnie to.
Adam
88

Zakładając, że przeniosłeś plik tekstowy data.txtdo swojego projektu Xcode (przeciągnij i upuść i zaznacz „Kopiuj pliki, jeśli to konieczne”), możesz wykonać następujące czynności, tak jak w 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

Aktualizacja:
Do odczytu pliku z pakietu (iOS) możesz użyć:

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

Aktualizacja dla 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)!

Dla 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
źródło
3
W przypadku projektów na iOS „stringWithContentsOfFile” jest niedostępny (nieaktualny od iOS 7)
od
1
Nie ma nic wspólnego z projektami na iOS, jest przestarzałe i nie działa już z Xcode 6.1 (w tym Mac OS X)
Leo Dabus
1
możesz użyć String (contentOfFile: ...)
shim
1
podobne rozwiązanie korzysta z pakietu z iOS 10 Swift 3 tutaj
Ponadczasowy
69

Xcode 8.x • Swift 3.x lub nowszy

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
źródło
Jakie są najczęstsze błędy „Nie ma takiego pliku”. Ponieważ dodałem moje pliki .txt do nawigatora projektu, a następnie próbuję je otworzyć, otrzymuję ten komunikat. (Utwórz je na pulpicie i przeciągnij do nawigatora projektu)
Darvydas,
56

Nowa, prostsza i zalecana metoda: Apple zaleca używanie adresów URL do obsługi plików, a inne rozwiązania tutaj wydają się przestarzałe (patrz komentarze poniżej). Oto nowy prosty sposób czytania i pisania za pomocą adresów URL (nie zapomnij poradzić sobie z możliwymi błędami adresów URL):

Swift 5+, 4 i 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
źródło
1
Czy możesz podać odniesienie, w którym Apple zaleca taki sposób. Czy możesz bardziej szczegółowo wyjaśnić, dlaczego jest to zalecany sposób?
Andrej
6
@Andrej „Obiekty URL to preferowany sposób odwoływania się do plików lokalnych. Większość obiektów, które odczytują dane lub zapisują dane do pliku, mają metody, które akceptują obiekt NSURL zamiast nazwy ścieżki jako odniesienie do pliku.” developer.apple.com/library/ios/documentation/Cocoa/Reference/…
Sverrisson
1
Nie musisz rzucać błędów jako NSError, ani nawet używać „catch let error”. Możesz po prostu złapać, a otrzymasz zmienną błędu za darmo.
cuomo456,
@ cuomo456 masz prawo, usuwam go, jest to pozostałość po poprzedniej wersji beta Swift.
Sverrisson,
1
@Alshcompiler The create: true informuje FileManagera, aby utworzył katalog, jeśli jeszcze go nie ma, zamiast
zawieść
28

Xcode 8, Swift 3 sposób na odczyt pliku z pakietu aplikacji:

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)")
} 

Oto wygodne rozszerzenie kopiuj i wklej

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 ""
    }
    }

Na przykład

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

Prawie zawsze potrzebujesz tablicy linii:

let r:[String] = "yourFile.txt"
     .contentsOrBlank()
     .characters
     .split(separator: "\n", omittingEmptySubsequences:ignore)
     .map(String.init)
Crashalot
źródło
2
Wkleiłem w przydatne rozszerzenie @crashalot - nie krępuj się usunąć, wiwaty
Fattie
1
@Alshcompiler NO! Nie można ZAPISOWAĆ pliku do pakietu.
Sverrisson
Mówiłem o czytaniu z pliku, to jedyna odpowiedź, która ze mną zadziałała, jeśli plik znajduje się w plikach projektu
kompilator Alsh
10

Chcę ci pokazać tylko pierwszą część, czyli przeczytaną . Oto jak możesz po prostu przeczytać:

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
źródło
5

Najprostszy sposób na odczytanie pliku w 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
źródło
3

Obecna zaakceptowana powyżej odpowiedź Adama zawierała dla mnie pewne błędy, ale oto, jak przerobiłem jego odpowiedź i sprawiłem, że to działa dla mnie.

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
źródło
3

Może się okazać, że to narzędzie jest przydatne nie tylko do odczytu z pliku w Swift, ale także do analizy danych wejściowych: https://github.com/shoumikhin/StreamScanner

Po prostu określ ścieżkę pliku i ograniczniki danych w następujący sposób:

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
    }
}

Mam nadzieję że to pomoże.

shoumikhin
źródło
2

Musiałem przekodować w ten sposób:

let path = NSBundle.mainBundle().pathForResource("Output_5", ofType: "xml")
let text = try? NSString(contentsOfFile: path! as String, encoding: NSUTF8StringEncoding)
print(text)
Nagarjun
źródło
2

W przykładzie funkcji (odczyt | zapis) DocumentsFromFile (...) z pewnymi opakowaniami funkcji z pewnością wydaje się mieć sens, ponieważ wszystko w OSx i iOS wydaje się wymagać utworzenia trzech lub czterech głównych klas oraz szeregu właściwości, skonfigurowanych, połączonych, utworzono instancję i ustawiono, aby napisać „Cześć” do pliku w 182 krajach.

Jednak te przykłady nie są wystarczająco kompletne, aby można je było wykorzystać w prawdziwym programie. Funkcja zapisu nie zgłasza żadnych błędów podczas tworzenia lub zapisu do pliku. Po przeczytaniu nie sądzę, że dobrym pomysłem jest zwrócenie błędu, że plik nie istnieje jako ciąg znaków, który powinien zawierać odczytane dane. Chcesz wiedzieć, że to się nie udało i dlaczego, za pomocą mechanizmu powiadamiania, takiego jak wyjątek. Następnie możesz napisać kod, który pokazuje, na czym polega problem i pozwala użytkownikowi go naprawić lub „poprawnie” zepsuć program w tym momencie.

Nie chcesz po prostu zwracać ciągu z napisem „Plik błędu nie istnieje”. Następnie należy za każdym razem szukać błędu w łańcuchu wywołania funkcji i tam go obsłużyć. Prawdopodobnie nie możesz naprawdę stwierdzić, czy łańcuch błędu został odczytany z rzeczywistego pliku, czy też został wygenerowany z Twojego kodu.

Nie można nawet wywoływać odczytu w ten sposób w szybkich wersjach 2.2 i Xcode 7.3, ponieważ NSString (contentOfFile ...) zgłasza wyjątek. Jest to błąd czasu kompilacji, jeśli nie masz żadnego kodu, aby go złapać i coś z nim zrobić, na przykład wydrukować go na standardowe wyjście, lub lepiej, wyskakujące okno błędu lub stderr. Słyszałem, że Apple odchodzi od try catch i wyjątków, ale będzie to długi krok i bez tego nie będzie możliwe pisanie kodu. Nie wiem, skąd pochodzi argument & error, być może starsza wersja, ale NSString.writeTo [Plik | URL] nie ma obecnie argumentu NSError. Są one zdefiniowane w ten sposób w 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

Ponadto plik nieistniejący jest tylko jednym z wielu potencjalnych problemów, które Twój program może odczytać, takich jak problem z uprawnieniami, rozmiar pliku lub wiele innych problemów, dla których nie chcesz nawet kodować procedury obsługi każdy z nich. Najlepiej po prostu założyć, że wszystko jest poprawne i złapać i wydrukować lub obsłużyć wyjątek, jeśli coś pójdzie nie tak, poza tym w tym momencie tak naprawdę nie masz wyboru.

Oto moje przepisania:

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
źródło
W wielu twoich odpowiedziach myślę, że nie rozumiesz, o co mi chodzi. (lub możesz się tym nie przejmować i to jest ok) Jednak, aby być jasnym, zgłaszanie wyjątku i jego obsługa w jakiś sposób, gdy szukasz pliku, którego nie ma (lub ma inny problem, taki jak pozwolenie), jest o wiele lepsze niż zwracanie ciągu, takiego jak „BŁĄD: Plik [nazwa pliku] nie istnieje ”jako ciąg, który miałeś odczytać z pliku. Więc po prostu to wydrukuj. Jeśli cokolwiek powinieneś wydrukować szczegóły wyjątku, a nie ciąg nie do odczytania, który ma teraz błąd. Program prawdopodobnie nie powinien po prostu kontynuować.
Sam Allen
2

Mój plik txt działa w ten sposób:

let myFileURL = NSBundle.mainBundle().URLForResource("listacomuni", withExtension: "txt")!
let myText = try! String(contentsOfURL: myFileURL, encoding: NSISOLatin1StringEncoding)
print(String(myText))
Alessandro Mattiuzzi
źródło
2

Aby uniknąć nieporozumień i dodać łatwości, stworzyłem dwie funkcje do odczytu i zapisu ciągów do plików w katalogu dokumentów. Oto funkcje:

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
}

Oto przykład ich użycia:

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.'

Mam nadzieję że to pomoże!

Wersja Xcode: 6.3.2

gooroo7
źródło
2

Najnowszy kod swift3
Możesz odczytać dane z pliku tekstowego, użyj poniższego kodu To mój plik tekstowy

     {
"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)"
           }]

}

Możesz użyć tego kodu, aby uzyskać dane z tekstowego pliku json w 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
źródło
2

Działa to z Swift 3.1.1 w systemie Linux:

import Foundation

let s = try! String(contentsOfFile: "yo", encoding: .utf8)
Adam Dingle
źródło
1

napisz w 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
źródło
1

Wcześniejsze rozwiązania odpowiadają na pytanie, ale w moim przypadku usunięcie starej zawartości pliku podczas pisania było problemem.

Stworzyłem więc fragment kodu do zapisu do pliku w katalogu dokumentów bez usuwania poprzedniej zawartości. Prawdopodobnie potrzebujesz lepszej obsługi błędów, ale uważam, że to dobry punkt wyjścia. Swift 4. Typage:

    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)
    }

Metody pomocnicze:

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
źródło
1

Swift 3.x - 5.x

Najlepszym przykładem jest utworzenie lokalu Logfilez rozszerzeniem, .txt które będzie widoczne i widoczne w"Files App" z bieżącą datą i godziną jako nazwą pliku

wystarczy dodać ten kod w info.plist włączyć te dwie funkcje

  UIFileSharingEnabled
  LSSupportsOpeningDocumentsInPlace

i ta funkcja poniżej

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
źródło
Próbowałem tego, ale musiałem coś przeoczyć. Zapisuje mój dokument i umieszcza go w pliku: /// var / mobile / Containers / Data / Application / E4BF1065-3B48-4E53-AC1D-0DC893CCB498 / Documents / ale nie mogę go znaleźć w plikach.
user3069232
1
Brakowało mi TEGO klucza ... <key> CFBundleDisplayName </key> <string> $ {PRODUCT_NAME} </
entry
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
źródło
0

Xcode 8.3.2 Swift 3.x . Korzystanie z NSKeyedArchiver i NSKeyedUnarchiver

Odczytywanie pliku z dokumentów

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")
}

Zapisz plik do dokumentów

NSKeyedArchiver.archiveRootObject(finalDataDict, toFile:(jsonFilePath?.absoluteString)!)
Prashant Gaikwad
źródło