Reputation: 4184
I want to start a python program from inside a scala program that has to receive a possibly infinitely long string. Thus it is not possible to pass it as a cmd argument.
My solution is to transmit the data via the stdstreams. However, I am unable to find the scala version of the working bash code:
bash code:
#/bin/bash
var="SOME REALLY LONG STRING THAT IS SEND TO THE PYTHON PROGRAM"
echo "$var" | ./readUntilEOF.py
scala code:
import sys.process._
object main {
def main(args : Array[String]) : Unit = {
val cmd = "./readUntilEOF.py"
val string = "SOME REALLY LONG STRING THAT IS SEND TO THE PYTHON PROGRAM"
print("I am starting to send stuff...")
val resultString = (string #| cmd.!!).!!
print(resultString)
}
}
readUntilEOF.py:
#!/usr/bin/python3
import sys
if __name__ == "__main__":
read = sys.stdin.read()
print(read)
Output running the bash command:
#> ./scalaBashEquivalent.sh
SOME REALLY LONG STRING THAT IS SEND TO THE PYTHON PROGRAM
Output running the scala code:
#> scala scala.sc
I am starting to send stuff...
/* and then it never terminates */
Upvotes: 0
Views: 121
Reputation: 48410
#<
can take InputStream
so try
(cmd #< new ByteArrayInputStream(string.getBytes)).!!
Upvotes: 2
Reputation: 4184
It is indeed a bit more complex than expected. But the below code seems to work.
import java.io.PrintWriter
object main {
def main(args : Array[String]) : Unit = {
val cmd = "./readUntilEOF.py"
val string = "SOME REALLY LONG STRING THAT IS SEND TO THE PYTHON PROGRAM"
println("I am starting to send stuff...")
val processOutput : StringBuilder = new StringBuilder()
val process = Process(cmd).run(new ProcessIO(
in => {
val writer = new PrintWriter(in)
writer.write(string)
writer.close()
},
out => {
processOutput.addAll(scala.io.Source.fromInputStream(out))
out.close()
},
_.close()
))
assert(process.exitValue() == 0)
print(processOutput.toString)
}
}
Upvotes: 0