首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用NSFileHandle的readabilityHandler检查文件结尾?

如何使用NSFileHandle的readabilityHandler检查文件结尾?
EN

Stack Overflow用户
提问于 2013-04-06 21:12:53
回答 3查看 2.6K关注 0票数 13

我正在使用readabilityHandler块从NSFileHandle (从NSPipe)读取数据:

代码语言:javascript
复制
fileHandle.readabilityHandler = ^( NSFileHandle *handle ) {
     [self processData: [handle availableData]];
}

这很好用,我得到了所有我期望输入到processData方法中的数据。问题是我需要知道最后一块数据是什么时候读取的。如果到达文件末尾,availableData应该返回一个空的NSData实例,但问题是在EOF上不会再次调用可达性处理程序。

我找不到任何关于如何在EOF上获得某种通知或回调的内容。那么我错过了什么呢?Apple真的提供了一个没有EOF回调的异步读取API吗?

顺便说一下,我不能使用基于runloop的readInBackgroundAndNotify方法,因为我没有可用的runloop。如果我不能让它与NSFileHandle应用程序接口一起工作,我可能会直接使用分派源来执行IO。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-02-13 17:18:24

如果你不能使用NSFileHandle,恐怕你用readInBackgroundAndNotify做这件事就不走运了。

我看到了两种解决方案:

创建一个运行循环,然后通过dispatch_io_*使用readInBackgroundAndNotify.

  • Roll您自己的实现
票数 0
EN

Stack Overflow用户

发布于 2018-09-29 11:56:48

我个人将当前文件偏移量与当前文件位置进行比较,然后停止读取。

代码语言:javascript
复制
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。

票数 3
EN

Stack Overflow用户

发布于 2020-02-23 05:12:53

我相信大家接受的答案其实是不正确的。当到达EOF时,确实会调用readabilityHandler。这是通过让availableData的大小为0来表示的。

这里有一个简单的游乐场可以证明这一点。

代码语言:javascript
复制
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
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15851391

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档