我怎么知道什么时候FileHandle没有什么要读取的? [英] How can I tell when a FileHandle has nothing left to be read?
问题描述
我正在尝试使用 Pipe
的 fileHandleForReading
的 standardOutput
和 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屋!