[英]How to check for End-of-File using NSFileHandle's readabilityHandler?
我正在使用NSPipe
块从NSFileHandle
(来自NSPipe
) readabilityHandler
数据:
fileHandle.readabilityHandler = ^( NSFileHandle *handle ) {
[self processData: [handle availableData]];
}
这很好用,我得到了我期望输入到我的processData
方法的所有数据。 问题是我需要知道最后一块数据是什么时候读取的。 availableData
到达文件结尾,则它应该返回一个空的NSData
实例,但问题是在 EOF 上不会再次调用可达性处理程序。
我找不到有关如何在 EOF 上获得某种通知或回调的任何信息。 那么我错过了什么? 苹果真的提供了没有 EOF 回调的异步读取 API 吗?
顺便说一下,我不能使用基于readInBackgroundAndNotify
方法,因为我没有可用的 runloop。 如果我不能NSFileHandle
与NSFileHandle
API 一起工作,我可能会直接使用调度源来执行 IO。
我个人将当前文件偏移量与当前文件位置进行比较并停止阅读。
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
}
}
}
很长一段时间我都无法理解为什么它是这样设计的,但现在我认为这可能是故意的。
在我看来,Apple 基本上将FileHandle
定义为无限流,因此,除非您关闭文件,否则 EOF 定义不明确。 FileHandle
似乎更像是一个“通道”。
还不清楚如果另一个进程在您读取文件时向文件中添加/删除一些数据/从文件中删除会发生什么。 在这种情况下,EOF 是什么? 据我所知,Apple 文档中没有提及此案例。 据我所知,macOS 中没有像其他类 Unix 系统那样真正的独占文件 I/O 锁。
在我看来,如果 I/O 不够快, availableData
可以随时返回空数据,而readabilityHandler
只是不关心 EOF。
我相信接受的答案实际上是不正确的。 当达到 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 = true
如果你不能使用readInBackgroundAndNotify
恐怕你不走运NSFileHandle
这样做。
我看到的两种解决方案:
readInBackgroundAndNotify
。dispatch_io_*
滚动你自己的实现
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.