“contentsOfFile” returning nil, possible cause

2020-06-18 06:31发布

问题:

The following returns nil when getting the content of a csv file. However, reducing the csv table to 10 rows will work properly, outputting the content of the csv file.

The original csv has about 400,000 characters arranged in 500 rows and 11 columns. What could be causing it to return nil with the original csv?

let dbPath = "/Volumes/Gios2TWD/myDB.csv"

var error: NSError?

let csvContent = NSString(contentsOfFile: dbPath, encoding:NSUTF8StringEncoding, error: &error) as String!

println(csvContent)

println(error)

I'm running XCode Version 6.1 (6A1030)

error:

Optional(Error Domain=NSCocoaErrorDomain Code=261 "The file “myDB.csv” couldn’t be opened using text encoding Unicode (UTF-8)." UserInfo=0x10050c5b0 {NSFilePath=/Volumes/Gios2TWD/myDB.csv, NSStringEncoding=4})

回答1:

You need code that tests for errors something like this:

let dbPath = "/Volumes/Gios2TWD/myDB.csv"
var error: NSError?
let csvContent = NSString(contentsOfFile: dbPath, encoding:NSUTF8StringEncoding, error: &error)
if csvContent != nil {
    // do something with the string
}
else {
    println("error: \(error)")
}

Then try to understand any error message. Post the code and full error message to SO if you need help.

With an error message like: "couldn’t be opened using text encoding Unicode (UTF-8)" it is not a UTF-8 file. There may be corruption in the file or it many be another format. Try NSMacOSRomanStringEncoding, it is an 8-bit ASCII encoding that is very forgiving. It also might be another 8-bit ASCII encoding.

Note: Do not explicitly unwrap things unless you are 100% certain that under no circumstances they can never be nil.



回答2:

Just stumbled upon this question and Zaph's answer with the recommendation to use NSMacOSRomanStringEnconding as the enconding does fix alot of issues indeed - in my case it were umlauts which caused the issue with NSUTF8StringEnconding.

Nevertheless I just wanted to add the latest Swift syntax in case you wanna catch the error and handle it properly

let csvContent: String?
do{
    csvContent = try String(contentsOfFile: path!, encoding: NSUTF8StringEncoding)
    // file could be read properly - do something with the content ...
} catch {
    let nsError = error as NSError
    print(nsError.localizedDescription)
}