Scala 如何使用ProcessBuilder返回二进制数据?

Scala 如何使用ProcessBuilder返回二进制数据?,scala,process,Scala,Process,我想使用scala.sys.process将图形的点描述发送到DOT,并检索到二进制图像的转换 val process = "dot -T" + format val inputStream = new ByteArrayInputStream(dot.getBytes("UTF-8")) process #< inputStream !! val process=“dot-T”+格式 val inputStream=new ByteArrayInputStream(dot.getByt

我想使用
scala.sys.process
将图形的点描述发送到
DOT
,并检索到二进制图像的转换

val process = "dot -T" + format
val inputStream = new ByteArrayInputStream(dot.getBytes("UTF-8"))
process #< inputStream !!
val process=“dot-T”+格式
val inputStream=new ByteArrayInputStream(dot.getBytes(“UTF-8”))
进程#<输入流!!

这很好,但是
返回一个
字符串,而不是
数组[字节]
。如何以字节而不是字符串获取响应?我不认为我可以使用字符串作为中间表示,因为二进制数据不会描述有效的字符串。

如果您确实想避免文件IO,并且您可以在Linux(或同等版本)下访问
base64
命令行程序,您可以

val进程=Seq(“bash”、“-c”、“dot-T”+格式+“| base64”)
val inputStream=new ByteArrayInputStream(dot.getBytes(“UTF-8”))
javax.xml.bind.DatatypeConverter.parseBase64Binary(进程#
以获取字节数组


您还可以提供自己的ProcessIO,在输入/输出流上使用二进制数据方法,但这需要做更多的工作。但是,如果base64太慢,那么它可能是值得的。(我认为点本身会成为瓶颈,但我不确定您发送的是什么。)

Scala进程IO很整洁,但我总是发现很难想出如何做我想要的事情。希望这个例子能对其他人有所帮助。一旦我找到了正确的巫毒,我想要的就很容易了。这是一个函数,它将参数带到
dot
,然后运行该过程,在
InputStream
中管道化,并在
OutputStream
中管道化

  def dotbin(format: String)(dot: String): Array[Byte] = {
    val process = "dot -T" + format
    val bos = new ByteArrayOutputStream()
    val exitCode = process #< new ByteArrayInputStream(dot.getBytes) #> bos !< ProcessLogger(s => ())
    if (exitCode == 0) {
      bos.toByteArray()
    }
    else {
      throw new RuntimeException("Nonzero exit value (" + exitCode + ") for '" + process + "' with: " + dot)
    }
  }
def dotbin(格式:字符串)(点:字符串):数组[字节]={
val process=“dot-T”+格式
val bos=新的ByteArrayOutputStream()
val exitCode=process#bos!())
if(exitCode==0){
bos.toByteArray()
}
否则{
使用“+dot”为“+process+”抛出新的RuntimeException(“非零出口值(“+exitCode+”)”)
}
}

一旦你找到了正确的符号,它就会变得简洁明了。请注意,在
2.10
中,您不需要为
提供
进程记录器
!将点写入一个文件并从Scala读取该文件?这会起作用,但我希望有办法避免文件io。还是我忽略了一个复杂的问题?
  def dotbin(format: String)(dot: String): Array[Byte] = {
    val process = "dot -T" + format
    val bos = new ByteArrayOutputStream()
    val exitCode = process #< new ByteArrayInputStream(dot.getBytes) #> bos !< ProcessLogger(s => ())
    if (exitCode == 0) {
      bos.toByteArray()
    }
    else {
      throw new RuntimeException("Nonzero exit value (" + exitCode + ") for '" + process + "' with: " + dot)
    }
  }