当前位置 : 主页 > 手机开发 > 其它 >

swift – 如何判断FileHandle什么都没有被读取?

来源:互联网 收集:自由互联 发布时间:2021-06-11
我正在尝试使用 Pipe 的 fileHandleForReading readabilityHandler 读取 Process 的 standardOutput 和 standardError .但是, terminationHandler 被调用的那一刻实际上是在我第一次调用readabilityHandler之前. 我不确定
我正在尝试使用 PipefileHandleForReading readabilityHandler读取 ProcessstandardOutputstandardError.但是, 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)!)
}
网友评论