Erstellen einer Sicherungskopie beim Laden einer Datei

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Erstellen einer Sicherungskopie beim Laden einer Datei

    Hallo in die Runde,

    ich habe einen einfachen Texteditor programmiert der mir in einer View den Inhalt einer *.txt Datei anzeigt.
    Ich möchte, wenn eine Datei geöffnet wird, von dieser automatisch eine Sicherungskopie erstellen. Diese Datei bekommt die Dateiendung *.bak und wird im gleichen Verzeichnis gespeichert.

    Ich wollte hier fragen, ob es zu meinem Code Verbesserungsvorschläge gibt (eventuell effizientere Wege) und wäre für jeden Hinweis sehr dankbar.

    So sieht meine aktuelle Methode aus:


    @IBAction func ladenClicked(_ sender: AnyObject) {
    let meinOeffnenDialog = NSOpenPanel()
    meinOeffnenDialog.title = "Öffnen"
    meinOeffnenDialog.prompt = "Öffnen"
    meinOeffnenDialog.allowedFileTypes = ["txt"]

    if meinOeffnenDialog.runModal() == NSApplication.ModalResponse.OK {
    let meineDatei = meinOeffnenDialog.url?.path

    var neueDatei = NSString(string: meineDatei!)
    neueDatei = neueDatei.deletingPathExtension as NSString
    neueDatei = (neueDatei.appendingPathExtension("bak") as NSString?)!
    let neueBakDatei: String = String(neueDatei)

    do {
    let textTemp = try String(contentsOfFile: meineDatei!, encoding: String.Encoding.utf8)
    try textTemp.write(toFile: neueBakDatei, atomically: true, encoding: String.Encoding.utf8)
    meinTextfeld.stringValue = textTemp
    } catch {
    print(error)
    }
    }
    }

    Lieben Gruß
  • Keine direkte Korrektur, aber zwei Anmerkungen:
    • Warum willst Du beim Öffnen eine Sicherungskopie anlegen? Ich würde es vor‘m Speichern machen. Ansonsten bekommt man ja x Kopien, wenn man Dateien nur anschaut.
    • Soll die App in einer Sandbox laufen, zum Bespiel weil sie in den Mac App Store kommt? Dann prüfe mal genau, ob Du die Sicherungskopie so ohne weiteres schreiben kannst. Ich bin gerade nicht sicher, Lesen ginge definitiv nicht. Die Lösung dafür heisst dann „relative items“...
    Mattes

    P.S.: Könntest Du für Code bitte das entsprechende Tag verwenden...
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Hi Mattes,

    danke für dein Feedback. Ich hatte hier schon mal im Forum nach entsprechenden Tag für die Codes gefragt, hab aber keine Antwort bekommen. Vielleicht sagst du mir, wie ich die Codes richtig posten kann. Ist dann natürlich besser lesbar.

    Zu Punkt 1: Die Aufgabenstellung in der Uni gab es so vor. Ich gebe dir hier natürlich Recht. (Mir ging es jetzt wirklich nur darum, ob meine Lösung vielleicht noch "besser(effektiver oder kürzer)" geschrieben werden kann.)

    Zu Punkt 2: Sandbox ist deaktiviert. Die App dient lediglich zur Übung.

    Also danke dir, und ich bitte noch um Hilfe zum richtigen Code posten ;)

    LG
  • Hey ihr Zwei,

    Ich habe eine neue Aufgabe bekommen, in dem ich die Methode zum Speichern so ändern soll, dass nur dann nach einem Namen für die Datei gefragt wird, wenn die Datei nicht schon einmal gespeichert wurde. Ich soll also zwischen dem ersten und allen nachfolgenden Speichervorgängen unterscheiden. Beim ersten Speichern muss der Dialog zur Eingabe des Namens erscheinen, bei allen weiteren Speichervorgängen soll direkt gespeichert werden.
    Ebenso soll bei einer Datei, die ich geladen habe auch beim ersten Speichern kein Dialog erscheinen, sondern die Datei soll direkt unter dem Namen gespeichert werden, unter dem es geladen wurde.

    Es geht mir hier wieder einzig und allein darum, ob ich die Aufgabe richtig angegangen bin, oder ob ich mit den If Verzweigungen zu kompliziert denke und es vielleicht doch einen simpleren Weg gibt.

    Hier dazu mein Code diesmal richtig gepostet :D

    Quellcode

    1. @IBAction func speichernClicked(_ sender: AnyObject) {
    2. if dateiWurdeGeladen == true {
    3. let textTemp = meinTextfeld.stringValue
    4. do {
    5. try textTemp.write(toFile: loadedFilePath!, atomically: true, encoding: String.Encoding.utf8)
    6. dateiWurdeGespeichert = true
    7. } catch {
    8. print(error)
    9. }
    10. }else if dateiWurdeGeladen == false && dateiWurdeGespeichert == true {
    11. let textTemp = meinTextfeld.stringValue
    12. do {
    13. try textTemp.write(toFile: savedFilePath!, atomically: true, encoding: String.Encoding.utf8)
    14. dateiWurdeGespeichert = true
    15. } catch {
    16. print(error)
    17. }
    18. }else if dateiWurdeGeladen == false && dateiWurdeGespeichert == false {
    19. let meinSpeichernDialog = NSSavePanel()
    20. meinSpeichernDialog.title = "Speichern unter"
    21. meinSpeichernDialog.prompt = "Speichern unter"
    22. meinSpeichernDialog.allowedFileTypes = ["txt"]
    23. if meinSpeichernDialog.runModal() == NSApplication.ModalResponse.OK {
    24. let meineDatei = meinSpeichernDialog.url?.path
    25. savedFilePath = meineDatei!
    26. let textTemp = self.meinTextfeld.stringValue
    27. do {
    28. try textTemp.write(toFile: meineDatei!, atomically: true, encoding: String.Encoding.utf8)
    29. dateiWurdeGespeichert = true
    30. }catch {
    31. print(error)
    32. }
    33. }
    34. }
    35. }
    Alles anzeigen
    Danke, dass ihr euch die Zeit für mich nimmt :thumbsup:
  • Hallo!

    Ich finde das zumindest unübersichtlich. Das Speichern selbst ist drei Mal im Code.
    Ich würde die Methode aufteilen, so dass speichernClicked nur zwei Methodenaufrufe
    verbleiben:

    C-Quellcode

    1. if let dateiName = ermittleDateiNameZumSpeichern() {
    2. textSpeichern(self.meinTextFeld.stringValue, in: dateiName)
    3. }
    In ermittleDateiNameZumSpeichern müsstest du dann entsprechend der drei Fälle
    den Dateinamen zurückgeben und in textSpeichern würde nur der do .. catch-Part stehen.

    Dann würde ich prüfen, ob das mit den verschiedenen Dateinamen so geschickt ist. Hängt aber
    vom übrigen Code ab.

    Grüße
    Marco
  • Hallo marcoo,

    lieb von dir, dass du dir mein Code angeschaut hast. :thumbup:

    Mir selbst kamen die ganzen If Verzweigungen auch zuviel vor, daher hab ich es auch hier gepostet, weil ich mir schon dachte, dass geht sicher auch etwas übersichtlicher.
    Sobald ich zu Hause bin, werde ich versuchen dein Vorschlag umzusetzen. Noch hab ich keine Idee, wie genau ich die Methode "ermittleDateiNamenZumSpeichern" umsetzen soll.

    Danke und Gruß
    Sascha
  • Ich würde das ganz simpel über das Vorhandensein des Dateipfades abwickeln.
    • Eine geladene Datei hat einen Dateipfad. Den muss man sich nur merken
    • Eine neue, noch nicht gespeicherte Datei hat keinen Dateipfad. Man muss danach fragen.
    • Eine bereits gespeicherte Datei hat einen Dateipfad. Den muss man sich nur merken.
    Es reicht also eine einzige Abfrage: ist ein Dateipfad vorhanden? Ja oder nein. Die Unterscheidung, ob eine Datei geladen wurde oder nicht ist irrelevant.