Я хочу запустить команду и получить вывод без промежуточных файлов.Обычно это работает, но иногда усекает вывод.
Например, если я запусту эту программу, она всегда будет генерировать один и тот же вывод и посчитает количество байтов на нем:
object BugTest extends App {
import java.io.ByteArrayOutputStream
import scala.language.postfixOps
import scala.sys.process._
def run(): Array[Byte] = {
val os = new ByteArrayOutputStream()
val stderr = new StringBuilder
val processLogger = ProcessLogger(x => stderr.append(x + "\n"), x => stderr.append(x + "\n"))
val code = Seq("seq", "10000") #> os ! processLogger
if (code != 0)
throw new Exception(s"Got code $code: ${stderr.mkString}")
os.close()
os.toByteArray
}
val reference = run().size
println(reference)
var current = 0
do {
current = run().size
println(current)
} while (current == reference)
}
Этослучайно произойдет сбой с выходом, который меньше, чем правильный.Пример выполнения:
48894
48894
48894
48894
48894
48894
48894
48894
48894
48128 <-- Truncated output !?
Что я делаю не так?
Примечание: проверено на Scala 2.12.6
Обновление:
Этот код кажетсяработать без каких-либо проблем (то есть он постоянно зацикливается, печатая 48894):
object BugTest extends App {
import java.io._
import scala.language.postfixOps
import scala.sys.process._
def outputProcessIO(stdout: OutputStream, stderr: OutputStream): ProcessIO = {
new ProcessIO(
_.close(),
(is: InputStream) => BasicIO.transferFully(is, stdout),
(is: InputStream) => BasicIO.transferFully(is, stderr)
)
}
def run(): Array[Byte] = {
val stdout = new ByteArrayOutputStream()
val stderr = new ByteArrayOutputStream()
val p = Seq("seq", "10000") run outputProcessIO(stdout, stderr)
if (p.exitValue() != 0)
throw new Exception(s"Got code $p: ${new String(stderr.toByteArray)}")
stdout.toByteArray
}
val reference = run().size
println(reference)
var current = 0
do {
current = run().size
println(current)
} while (current == reference)
}
Я все еще хотел бы знать, в чем проблема с исходным кодом.