我正在尝试使用 Pipe 的 fileHandleForReading readabilityHandler 读取 Process 的 standardOutput 和 standardError .但是, terminationHandler 被调用的那一刻实际上是在我第一次调用readabilityHandler之前. 我不确定
Pipe
的
fileHandleForReading
readabilityHandler
读取
Process
的
standardOutput
和
standardError
.但是,
terminationHandler
被调用的那一刻实际上是在我第一次调用readabilityHandler之前.
我不确定为什么这个过程会这样做,但这意味着我没有获得所有数据,因为我假设进程终止意味着所有输出都被刷新到管道.既然不是这样,有没有办法告诉我什么时候没有更多的输出要读?我假设涉及检查FileHandle
是否仍然打开,但我没有看到API.
以下是我的代码的基本概念示例:
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
在文件句柄上,在这种情况下应该删除可读性处理程序.
在过程完成后,可以使用调度组在标准输出和标准错误上等待EOF.
例:
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)!) }