簡體   English   中英

如何使用 NSFileHandle 的 readabilityHandler 檢查文件結尾?

[英]How to check for End-of-File using NSFileHandle's readabilityHandler?

我正在使用NSPipe塊從NSFileHandle (來自NSPipereadabilityHandler數據:

fileHandle.readabilityHandler = ^( NSFileHandle *handle ) {
     [self processData: [handle availableData]];
}

這很好用,我得到了我期望輸入到我的processData方法的所有數據。 問題是我需要知道最后一塊數據是什么時候讀取的。 availableData到達文件結尾,則它應該返回一個空的NSData實例,但問題是在 EOF 上不會再次調用可達性處理程序。

我找不到有關如何在 EOF 上獲得某種通知或回調的任何信息。 那么我錯過了什么? 蘋果真的提供了沒有 EOF 回調的異步讀取 API 嗎?

順便說一下,我不能使用基於readInBackgroundAndNotify方法,因為我沒有可用的 runloop。 如果我不能NSFileHandleNSFileHandle 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這樣做。

我看到的兩種解決方案:

  1. 創建一個 runloop,然后使用readInBackgroundAndNotify
  2. 使用dispatch_io_*滾動你自己的實現

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM