[英]How can I tell when a FileHandle has nothing left to be read?
我試圖用一個Pipe
的fileHandleForReading
的readabilityHandler
讀兩個standardOutput
和standardError
一個的Process
。 然而,在調用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)!)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.