我怎么知道什么时候FileHandle没有什么要读取的? [英] How can I tell when a FileHandle has nothing left to be read?

查看:170
本文介绍了我怎么知道什么时候FileHandle没有什么要读取的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Pipe fileHandleForReading Process 的noreferrer> standardError .但是,调用 terminationHandler 的时刻实际上是之前,第一次调用我的readabilityHandler.

I'm trying to use a Pipe's fileHandleForReading's readabilityHandler to read both the standardOutput and standardError of a Process. However, the moment the terminationHandler is called is actually before the moment my readabilityHandler is called for the first time.

我不确定为什么进程会这样做,但是这意味着我没有获取所有数据,因为我认为进程终止意味着所有输出都已刷新到管道中.既然不是这种情况,我有办法告诉我何时没有更多的输出要读吗?我假设这涉及检查

I'm not sure why the process does this, but it means I'm not getting all the data, because I assume process termination means all output has been flushed to the pipe. Since this isn't the case, is there a way for me to tell when there is no more output to be read? I assume that involves checking if a FileHandle is still open, but I don't see an API for that.

这是我的代码的基本概念示例:

Here's an example of the basic idea of what my code looks like:

let stdOutPipe = Pipe()
let stdErrPipe = Pipe()

stdOutPipe.fileHandleForReading.readabilityHandler = { stdOutFileHandle in
    let stdOutPartialData = stdOutFileHandle.readDataToEndOfFile()

    guard !stdOutPartialData.isEmpty else {
        print("Time to read, but nothing to be read?") // happens a lot
        return
    }

    self.tempStdOutStorage.append(stdOutPartialData)
}

stdErrPipe.fileHandleForReading.readabilityHandler = { stdErrFileHandle in
    let stdErrPartialData = stdErrFileHandle.readDataToEndOfFile()

    guard !stdErrPartialData.isEmpty else {
        print("Time to read, but nothing to be read?") // happens a lot
        return
    }

    self.tempStdErrStorage.append(stdErrPartialData)
}

process.standardOutput = stdOutPipe
process.standardError = stdErrPipe


process.terminationHandler = { process in
    notifyOfCompleteRead(stdOut: self.tempStdOutStorage, stdErr: self.tempStdErrStorage)
}

mySpecializedDispatchQueue.async(execute: process.launch)

推荐答案

readabilityHandler中,您应使用availableData来获取 当前可用数据而不会阻塞.空的可用数据表示EOF 在这种情况下,应删除可读性处理程序.

In the readabilityHandler you should use availableData to get the currently available data without blocking. Empty available data indicates EOF on the file handle, in that case the readability handler should be removed.

在处理完成后,可以使用调度组来等待标准输出和标准错误的EOF.

A dispatch group can be used to wait for EOF on both standard output and standard error after the process has finished.

示例:

let group = DispatchGroup()

group.enter()
stdOutPipe.fileHandleForReading.readabilityHandler = { stdOutFileHandle in
    let stdOutPartialData = stdOutFileHandle.availableData
    if stdOutPartialData.isEmpty  {
        print("EOF on stdin")
        stdOutPipe.fileHandleForReading.readabilityHandler = nil
        group.leave()
    } else {
        tempStdOutStorage.append(stdOutPartialData)
    }
}

group.enter()
stdErrPipe.fileHandleForReading.readabilityHandler = { stdErrFileHandle in
    let stdErrPartialData = stdErrFileHandle.availableData

    if stdErrPartialData.isEmpty  {
        print("EOF on stderr")
        stdErrPipe.fileHandleForReading.readabilityHandler = nil
        group.leave()
    } else {
        tempStdErrStorage.append(stdErrPartialData)
    }
}

process.standardOutput = stdOutPipe
process.standardError = stdErrPipe

process.launch()

process.terminationHandler = { process in
    group.wait()
    print("OUTPUT:", String(data: tempStdOutStorage, encoding: .utf8)!)
    print("ERROR: ", String(data: tempStdErrStorage, encoding: .utf8)!)
}

这篇关于我怎么知道什么时候FileHandle没有什么要读取的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆