繁体   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