我有一个应用程序,它不一致地返回‘零’当使用FileHandle打开一个文件读。我在OSX (10.13.4),XCode 9.4,SWIFT4.1
这个OSX应用程序使用NSOpenPanel()获取用户选择的文件列表。我的“模型”类代码打开这些文件来构建一个数据结构集合--这样做的代码就这样开始,每次都成功地为任何文件获得一个FileHandle,并且能够从文件中读取数据。
private func getFITHeader(filename: String) {
let file: FileHandle? = FileHandle(forReadingAtPath: filename)
if file == nil {
print("FITFile >>> File open failed for file \(filename)")
}
else {
var databuffer: Data
databuffer = (file?.readData(ofLength: 80))!
:
:
}这些文件还包含一个二进制数据块,我在应用程序的另一部分处理这些数据。在为此开发代码时,为了测试目的,我暂时对其中一个文件名进行硬编码。但是,这段代码(下面)总是抛出一个异常‘线程1:致命错误:在打开可选值时意外地发现为零’--由于某种原因,创建FileHandle的尝试总是返回‘FileHandle’,尽管代码在功能上与上述代码相同。
@IBAction func btnProcFile(_ sender: Any) {
var data: Data
let filename = "/Users/johncneal/Dropbox/JN Astronomy/Astronomy/Spectroscopy/RSpec_Analyses/Gamma_Cas/20161203/Gamma Cas_065.fit"
let fileHandle: FileHandle? = FileHandle(forReadingAtPath: filename)
fileHandle?.seek(toFileOffset: 2880) //skip past the headers
let dataLenToRead = 1391 * 1039 * 2
data = (fileHandle?.readData(ofLength: dataLenToRead))!
:
:
}第二个函数中的代码在游乐场中工作得很好(没有附加太多的意义),而且,当临时添加到另一个项目时,代码也可以正常工作。也许还值得一提的是,文件路径的长度似乎并不重要--它在短路径上的行为也是一样的。
所以问题是为什么FileHandle的这种行为可靠地不一致?
打印()显示给FileHandle()的文件名在每一种情况下都是相同的(见下文)。因此,我对此感到困惑和沮丧--任何观点或解决办法都会受到欢迎。
/Users/johncneal/Dropbox/JN Astronomy/Astronomy/Spectroscopy/RSpec_Analyses/Gamma_Cas/20161203/Gamma Cas_065.fit
/Users/johncneal/Dropbox/JN Astronomy/Astronomy/Spectroscopy/RSpec_Analyses/Gamma_Cas/20161203/Gamma Cas_065.fit
发布于 2018-05-31 23:56:58
找到答案了-太极拳!
达伦--巧合的是,我确实看到了基于URL的路由,并发现它“抛出”,在捕获中添加了一些正确的错误报告。很低,他们报告说我对这个文件没有权限(这让我很惊讶,因为我显然是我的Mac的管理员,所有文件都是本地的,并且是在我的用户名下。)
我发现了更多的研究。这篇文章-- https://forums.developer.apple.com/thread/96062很快就暴露了它的沙箱问题:-)看起来就像XCode的最新版本在“权利”中打开了它。文章还指出,NSOpenPanel FileOpen对话框返回‘安全范围的urls’。起初,我认为这解释了为什么第一个函数中的代码可以工作,但我并不完全相信,因为我只是将url.path属性提供给FileHandle。
然而,关闭桑德盒的权利,使一切正常工作。是的,我知道做更长期的事情是不对的(或者如果我想让它去App ),所以我会检查一下正确的方法。至少我现在可以上了-谢谢你的意见。
发布于 2018-05-31 22:12:13
FileHandle初始化器没有很好的命名。
您应该使用FileHandle(forReadingFrom:URL)而不是FileHandle(forReadingAtPath:String)。前者是较新的API,它抛出错误,而不是返回零。您可以使用抛出的错误来查看其失败的原因,并且您的变量保证为非零。
例如:
@IBAction func btnProcFile(_ sender: Any) {
do {
let fileUrl = URL(fileURLWithPath:"/Users/johncneal/Dropbox/JN Astronomy/Astronomy/Spectroscopy/RSpec_Analyses/Gamma_Cas/20161203/Gamma Cas_065.fit")
let fileHandle = try FileHandle(forReadingFrom: fileUrl)
fileHandle.seek(toFileOffset: 2880) //skip past the headers
let dataLenToRead = 1391 * 1039 * 2
let data: Data = fileHandle.readData(ofLength: dataLenToRead)
// etc...
} catch let error as NSError {
print("FITFile >>> File open failed: \(error)")
NSApp.presentError(error)
}
}https://stackoverflow.com/questions/50632680
复制相似问题