[英]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.