我正在使用readabilityHandler块从NSFileHandle (从NSPipe)读取数据:
fileHandle.readabilityHandler = ^( NSFileHandle *handle ) {
[self processData: [handle availableData]];
}这很好用,我得到了所有我期望输入到processData方法中的数据。问题是我需要知道最后一块数据是什么时候读取的。如果到达文件末尾,availableData应该返回一个空的NSData实例,但问题是在EOF上不会再次调用可达性处理程序。
我找不到任何关于如何在EOF上获得某种通知或回调的内容。那么我错过了什么呢?Apple真的提供了一个没有EOF回调的异步读取API吗?
顺便说一下,我不能使用基于runloop的readInBackgroundAndNotify方法,因为我没有可用的runloop。如果我不能让它与NSFileHandle应用程序接口一起工作,我可能会直接使用分派源来执行IO。
发布于 2015-02-13 17:18:24
如果你不能使用NSFileHandle,恐怕你用readInBackgroundAndNotify做这件事就不走运了。
我看到了两种解决方案:
创建一个运行循环,然后通过dispatch_io_*使用readInBackgroundAndNotify.
发布于 2018-09-29 11:56:48
我个人将当前文件偏移量与当前文件位置进行比较,然后停止读取。
extension FileHandle {
func stopReadingIfPassedEOF() {
let pos = offsetInFile
let len = seekToEndOfFile()
if pos < len {
// Resume reading.
seek(toFileOffset: pos)
}
else {
// Stop.
// File offset pointer stays at the EOF.
readabilityHandler = nil
}
}
}我不明白为什么这么长时间以来都是这样设计的,但现在我认为这可能是故意的。
在我看来,苹果基本上将FileHandle定义为无限大的流,因此,除非您关闭文件,否则EOF不是很好的定义。FileHandle看起来更像是一个“渠道”。
当你从文件中读取数据时,如果另一个进程在文件中添加/删除了一些数据,会发生什么情况也是不清楚的。在这种情况下,EOF是多少?据我所知,在苹果的文档中没有提到这个案例。据我所知,在macOS中没有像其他类Unix系统那样的真正的独占文件I/O锁。
在我看来,如果I/O不够快,availableData可以在任何时候返回空数据,而readabilityHandler就是不关心EOF。
发布于 2020-02-23 05:12:53
我相信大家接受的答案其实是不正确的。当到达EOF时,确实会调用readabilityHandler。这是通过让availableData的大小为0来表示的。
这里有一个简单的游乐场可以证明这一点。
import Foundation
import PlaygroundSupport
let pipe = Pipe()
pipe.fileHandleForReading.readabilityHandler = { fh in
let d = fh.availableData
print("Data length: \(d.count)")
if (d.count == 0) {
fh.readabilityHandler = nil
}
}
pipe.fileHandleForWriting.write("Hello".data(using: .utf8)!)
pipe.fileHandleForWriting.closeFile()
PlaygroundPage.current.needsIndefiniteExecution = truehttps://stackoverflow.com/questions/15851391
复制相似问题