Swift - 文件路径不可用,除非是第一次使用
Swift - The file path is unavailable except for first time use
下面的代码是有效的。图像已成功保存在文档目录中,但问题只是第一次 collectionViewController 可以成功加载带有路径的图像。我必须删除所有图像才能存储新图像,否则会显示错误消息
"fatal error: unexpectedly found nil while unwrapping an Optional
value".
因为路径不可用,readnsdata = NSData(contentsOfFile: filepath)!
会报错
我不知道为什么只有第一次可以。
path :
"/var/mobile/Containers/Data/Application/29306029-BDCF-4BEA-93A6-D5626CBAAA90/Documents/x.jpg"
func writeNSDataToDisk(imageData:NSData){
let myindex = imgPathArray.count
let fileName = "\(self.imgPathArray.count)"
let paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
let docs: String = paths[0] as String
let filepath: String = (docs as NSString).stringByAppendingPathComponent("\(fileName).jpg")
let test = imageData.writeToFile(filepath, atomically: true)
if test {
self.imgPathArray.insert(filepath, atIndex: myindex)
print("The picture \(fileName).jpg is been saved.")
self.readORwriteList(true)//write list to txt file
}
print(self.imgPathArray)
}
func readNSDataFromDisk(fileIndex:Int) -> NSData{
let checkValidation = NSFileManager.defaultManager()
var readnsdata = NSData()
if (fileIndex <= self.imgPathArray.count) {
let filepath = self.imgPathArray[fileIndex]
if (checkValidation.fileExistsAtPath(filepath)){
print("File is available")
print("load \(fileIndex).jpg,filepath is \(filepath)")
readnsdata = NSData(contentsOfFile: filepath)!
if readnsdata.length != 0 {
getImageProperties(readnsdata)
}
}
else{
print("File is not available!!!")
}
}
return readnsdata
}
我的问题的解决方案:
我没有存储绝对文件路径,而是以常规方式命名文件并按名称搜索它们。不需要存储路径。
文件的 URL 现在是相对于文档目录 URL 每次应用 运行 构建的。
谢谢
将 readnsdata = NSData(contentsOfFile: filepath)!
替换为 readnsdata = NSData(contentsOfFile: filepath)?
。希望这会有所帮助:)
首先是旁注。 Apple 的 docs 特别建议不要像您在这里那样使用 fileExistsAtPath
。
NOTE
Attempting to predicate behavior based on the current state of
the file system or a particular file on the file system is not
recommended. Doing so can cause odd behavior or race conditions. It’s
far better to attempt an operation (such as loading a file or creating
a directory), check for errors, and handle those errors gracefully
than it is to try to figure out ahead of time whether the operation
will succeed.
尝试替换这个…
if (checkValidation.fileExistsAtPath(filepath)){
print("File is available")
print("load \(fileIndex).jpg,filepath is \(filepath)")
readnsdata = NSData(contentsOfFile: filepath)!
if readnsdata.length != 0 {
getImageProperties(readnsdata)
}
}
else{
print("File is not available!!!")
}
...有了这个...
do {
readnsdata = try NSData(contentsOfFile: filepath, options: .DataReadingMappedIfSafe)
if readnsdata.length != 0 {
getImageProperties(readnsdata)
}
}
catch let e {
print("Couldn't read file at \(filepath) because \(e)")
}
这种方法无需推测即可为您提供所需的信息。只是 运行 你的代码,看看当 NSData 初始化程序抛出时会发生什么! :)
[更新:题外话]
虽然不要在长方法中使用 return 是个好习惯,但这里并没有太多内容。就个人而言,我认为代码在没有临时 readnsdata
变量的情况下更具可读性。这样,imo,快乐路径和默认 return 值在第一次阅读时都很清楚:
func readNSDataFromDisk2(fileIndex:Int) -> NSData{
if (fileIndex <= self.imgPathArray.count) {
let path = self.imgPathArray[fileIndex]
do {
let data = try NSData(contentsOfFile: path, options: .DataReadingMappedIfSafe)
if data.length != 0 {
getImageProperties(data)
}
return data
}
catch let e {
print("Couldn't read file at \(path) because \(e)")
}
}
return NSData()
}
下面的代码是有效的。图像已成功保存在文档目录中,但问题只是第一次 collectionViewController 可以成功加载带有路径的图像。我必须删除所有图像才能存储新图像,否则会显示错误消息
"fatal error: unexpectedly found nil while unwrapping an Optional value".
因为路径不可用,readnsdata = NSData(contentsOfFile: filepath)!
会报错
我不知道为什么只有第一次可以。
path : "/var/mobile/Containers/Data/Application/29306029-BDCF-4BEA-93A6-D5626CBAAA90/Documents/x.jpg"
func writeNSDataToDisk(imageData:NSData){
let myindex = imgPathArray.count
let fileName = "\(self.imgPathArray.count)"
let paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
let docs: String = paths[0] as String
let filepath: String = (docs as NSString).stringByAppendingPathComponent("\(fileName).jpg")
let test = imageData.writeToFile(filepath, atomically: true)
if test {
self.imgPathArray.insert(filepath, atIndex: myindex)
print("The picture \(fileName).jpg is been saved.")
self.readORwriteList(true)//write list to txt file
}
print(self.imgPathArray)
}
func readNSDataFromDisk(fileIndex:Int) -> NSData{
let checkValidation = NSFileManager.defaultManager()
var readnsdata = NSData()
if (fileIndex <= self.imgPathArray.count) {
let filepath = self.imgPathArray[fileIndex]
if (checkValidation.fileExistsAtPath(filepath)){
print("File is available")
print("load \(fileIndex).jpg,filepath is \(filepath)")
readnsdata = NSData(contentsOfFile: filepath)!
if readnsdata.length != 0 {
getImageProperties(readnsdata)
}
}
else{
print("File is not available!!!")
}
}
return readnsdata
}
我的问题的解决方案:
我没有存储绝对文件路径,而是以常规方式命名文件并按名称搜索它们。不需要存储路径。
文件的 URL 现在是相对于文档目录 URL 每次应用 运行 构建的。
谢谢
将 readnsdata = NSData(contentsOfFile: filepath)!
替换为 readnsdata = NSData(contentsOfFile: filepath)?
。希望这会有所帮助:)
首先是旁注。 Apple 的 docs 特别建议不要像您在这里那样使用 fileExistsAtPath
。
NOTE
Attempting to predicate behavior based on the current state of the file system or a particular file on the file system is not recommended. Doing so can cause odd behavior or race conditions. It’s far better to attempt an operation (such as loading a file or creating a directory), check for errors, and handle those errors gracefully than it is to try to figure out ahead of time whether the operation will succeed.
尝试替换这个…
if (checkValidation.fileExistsAtPath(filepath)){
print("File is available")
print("load \(fileIndex).jpg,filepath is \(filepath)")
readnsdata = NSData(contentsOfFile: filepath)!
if readnsdata.length != 0 {
getImageProperties(readnsdata)
}
}
else{
print("File is not available!!!")
}
...有了这个...
do {
readnsdata = try NSData(contentsOfFile: filepath, options: .DataReadingMappedIfSafe)
if readnsdata.length != 0 {
getImageProperties(readnsdata)
}
}
catch let e {
print("Couldn't read file at \(filepath) because \(e)")
}
这种方法无需推测即可为您提供所需的信息。只是 运行 你的代码,看看当 NSData 初始化程序抛出时会发生什么! :)
[更新:题外话]
虽然不要在长方法中使用 return 是个好习惯,但这里并没有太多内容。就个人而言,我认为代码在没有临时 readnsdata
变量的情况下更具可读性。这样,imo,快乐路径和默认 return 值在第一次阅读时都很清楚:
func readNSDataFromDisk2(fileIndex:Int) -> NSData{
if (fileIndex <= self.imgPathArray.count) {
let path = self.imgPathArray[fileIndex]
do {
let data = try NSData(contentsOfFile: path, options: .DataReadingMappedIfSafe)
if data.length != 0 {
getImageProperties(data)
}
return data
}
catch let e {
print("Couldn't read file at \(path) because \(e)")
}
}
return NSData()
}