2

I know Python and I'm trying to learn Swift... I am trying to figure out how to just read a plain text file from an absolute file path

In Python,

#!/usr/bin/python

path= '/users/mu/desktop/test_file.txt'    
in_file= open(path,'w').read() #Open the file for reading

for line in in_file.split('\n'): #Split it by line breaks and print the lines
    print line

Tried this one: Swift - Read Files Got: "String.Type does not have a member name stringWithContentsOfFile"

In Python, it's so easy. There must be a really simple way to read a text file and create a list of strings separated by line breaks.

My question is how to read a text file so you can iterate through the lines

Once I read the file, I could just:

for line in in_file
    {
    println(line)
    }
Community
  • 1
  • 1
O.rka
  • 29,847
  • 68
  • 194
  • 309
  • 1
    FWIW, that's a terrible way to do it in Python. You should use `with open(path) as file: for line in file: print line`; your version is neither lazy nor closes the file. – Veedrac Mar 17 '15 at 02:48
  • I've not used Swift but I think you want http://stackoverflow.com/questions/24581517/read-a-file-url-line-by-line-in-swift. Actually, after reading that I'm pretty sure I'm not ever *going* to use Swift... – Veedrac Mar 17 '15 at 02:51
  • @veedrac does that close it or do I need to file.close() after? – O.rka Mar 17 '15 at 03:02
  • 1
    `with` will close it for you. – Veedrac Mar 17 '15 at 03:25
  • @Veedrac thanks for the heads up. i'm sure Swift is really annoying but I want to make apps and I feel like recreating my bioinformatic Python scripts would be the first step in learning to use Swift. – O.rka Mar 17 '15 at 04:11

3 Answers3

1

You can use NSFileManager and NSString to parse the lines eg :

    var path = "somePath"
    let fileManager = NSFileManager.defaultManager()
    let data:NSData = fileManager.contentsAtPath(path)!
    var strs = NSString(data: data, encoding: NSUTF8StringEncoding)
Sheen Vempeny
  • 818
  • 1
  • 5
  • 8
  • for var strs = NSString(data:data,encoding NSUTF8StringEncoding) I get an error telling me to add a , after encoding. when I add , it says "Use of unresolved identifier 'encoding'" – O.rka Mar 17 '15 at 09:29
  • it also had me add an ! after NSData in line 3 – O.rka Mar 17 '15 at 09:31
  • Corrected the mistakes in the answer – Sheen Vempeny Mar 17 '15 at 10:50
  • when I made the changes, there was an error the 3rd line "Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_l386_INVOP, subcode=0x0)." . I'll try and figure out what is meant by this error. – O.rka Mar 17 '15 at 19:07
  • I ran this in Xcode and got something weird but it works perfectly in the terminal – O.rka Mar 24 '15 at 15:05
1

Looking for a pythonic way of doing something in a language that isn't Python will often be doomed to failure. In conjunction with the various standard libraries, Python's string processing abilities far exceed those of Swift, and you'll just need to get used to that. However, in the simplest case, parsing lines from a file is still pretty straightforward. There are lots of ways of doing it, but the one below accomplishes it in a single call, once you've got the string:

import Foundation
import Cocoa

let filepath = "/Users/yourname/Desktop/greatspeeches.txt"

// 1. Safely load the string
var error: NSError?
let contents = NSString(contentsOfFile: filepath,
    encoding: NSUTF8StringEncoding,
    error: &error)

if let contentsString = contents {

    // 2. Enumerate the lines in the string
    contentsString.enumerateLinesUsingBlock({ (line, stopEarly) -> Void in
        println(line)
    })

} else if let err = error {

    println(err.localizedDescription)

}

Like you, I came to Objective-C/Swift from Python and was initially frustrated by the apparent difficulty of tasks like the one above. Once you get used to it though, the inconvenience encountered here is more than offset by the ease with with you can put together sophisticated Mac apps.

Paul Patterson
  • 6,840
  • 3
  • 42
  • 56
  • I feel like it's almost working but it says "The file "test" couldn't be opened because you don't have permissions to view it." So I went into the terminal and chmod 777 test.txt ... so now my permissions are "-rwxrwxrwx@ 1 Mu staff 48 Mar 15 03:41 test.txt" but I'm still getting that error. So weird? – O.rka Mar 19 '15 at 18:37
  • Where are you doing this from - a playground, a Cocoa app, or a command line app? – Paul Patterson Mar 19 '15 at 18:44
  • 1
    I think playgrounds are *sandboxed*, meaning they restrict the extent to which you can interact with the file-system. It's a security thing imposed by Apple, and it's probably the reason your code is failing. What's more I doubt you'll be able to get at any file on the system in a playground. Give the code a go in a command line app; if it works you'll know where the problem lies. – Paul Patterson Mar 19 '15 at 19:53
  • you're right. I ran it through the terminal and it worked. thank you so much. I need to look up some of the syntax you use...the "if let contentsString" is unfamiliar to me as well as the error checking method. – O.rka Mar 23 '15 at 16:44
1

I was searching for the same thing and found the following solution. The only drawback is that the file is not read line by line but at once and then split into lines. This answer is a little shorter than the accepted one and therefore seems more "python"-like to me.

import Foundation
let fileName = "file.txt"

let fileContents = try! String(contentsOfFile:fileName)
let lines = fileContents.components(separatedBy: "\n")

for line in lines {
   print(line)
}

This works nicely in terminal (tested with Swift version 3.0.2).

Kristiina
  • 523
  • 2
  • 10