【问题标题】:How can I tell when a FileHandle has nothing left to be read?我如何判断 FileHandle 何时没有任何内容可供阅读?
【发布时间】:2018-09-14 15:52:31
【问题描述】:

我正在尝试使用PipefileHandleForReadingreadabilityHandler 来读取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)

【问题讨论】:

    标签: swift cocoa nstask nsfilehandle nspipe


    【解决方案1】:

    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)!)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-13
      • 1970-01-01
      • 1970-01-01
      • 2015-04-05
      • 2012-02-26
      • 2014-08-20
      相关资源
      最近更新 更多