質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

2回答

4632閲覧

Javaで外部プロセスの出力がうまく取得できません

nitoa

総合スコア6

Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2016/11/22 19:03

JavaでProcessBuilderを利用してPerlを実行しているのですが、うまく出力ができません。
具体的には、今次のようなPerlのプログラムをJavaで動かしています。
<Perlのソースコード>
while($print=<STDIN>){
print $print;
}

このPerlのプログラムを実行して、出力を得ようと思っているのですが、Javaのプログラムが終了して出力結果を得るのではなく、標準入力してJavaプログラムが終了せずに出力を得たいのです。アルゴリズム的に説明しますと、
①Javaプログラム起動
②JavaプログラムからPerlのプログラムへ標準入力を行う(例えば"Hello World"とします)
③JavaプログラムがPerlのプログラムの標準出力(今回の例では"Hello World")を得る(このとき、Javaプログラムは終了しない)
④ ②と③を何回か繰り返して、Javaプログラム終了
というようなことをしたいのですが、何か助言等をいただけたらと思います。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

JavaでもPerlでもデフォルトで出力がバッファリングされているので、双方で出力のバッファリングを無効、フラッシュすると良いようです。

perlの標準出力から読み取るときに待ちが発生することもあるので、読み取って表示するスレッドは別にしました。

Java

1public class Popen extends Thread 2{ 3 static InputStream perlStdout = null; 4 5 public static void main(String[] args) 6 { 7 try { 8 Process process = new ProcessBuilder("C:/bin/perl", "C:/home/hello.pl").start(); 9 10 // perlの標準入力を取得 11 OutputStream perlStdin = process.getOutputStream(); 12 // perlの標準出力を取得 13 perlStdout = process.getInputStream(); 14 15 // perlの標準出力から読み取って表示するスレッドを作成・開始 16 Popen anotherInstance = new Popen(); 17 Thread perlOutputReadingThread = new Thread(anotherInstance); 18 perlOutputReadingThread.start(); 19 20 // perlの標準入力へ書き込む 21 perlStdin.write("Hello World!\n".getBytes()); 22 perlStdin.flush(); 23 24 perlStdin.write("Bonjour le Monde!\n".getBytes()); 25 perlStdin.flush(); 26 27 perlStdin.write("Buongiorno il Mondo!\n".getBytes()); 28 perlStdin.flush(); 29 30 perlStdin.write("Good bye!\n".getBytes()); 31 perlStdin.flush(); 32 33 // perlの標準入力を切断 34 perlStdin.close(); 35 } 36 catch (IOException e) 37 { 38 e.printStackTrace(); 39 } 40 } 41 42 // perlの標準出力から読み取って表示する 43 @Override 44 public void run() 45 { 46 byte[] inputBuf = new byte[512]; 47 String perlStr; 48 49 try { 50 do { 51 // 場合によっては待ちが発生することもある 52 perlStdout.read(inputBuf); 53 perlStr = new String(inputBuf); 54 System.out.print(perlStr); 55 // 読み取り可能なバイト数が 0 になるまで繰り返す 56 } while (perlStdout.available() > 0); 57 } 58 catch (IOException e) 59 { 60 System.out.println("IOException on perlOutputReadingThread"); 61 } 62 System.out.println("perlOutputReadingThread exited."); 63 } 64}

Perl

1# $| 出力のバッファリング、0以外でバッファリングが無効になる 2$| = 1; 3while ($print = <STDIN>) 4{ 5#Perlからの出力であることを示すために'perl:'をつけて出力 6 print 'perl:' . $print; 7}

投稿2016/11/22 21:46

編集2016/11/26 11:45
naomi3

総合スコア1105

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

以下のようにすると実現できます。
バッファのフラッシュを忘れないようにしましょう。

perl

1#!/usr/bin/perl 2$| = 1; 3while($print=<STDIN>){ 4 print $print; 5}

Java

1import java.io.BufferedOutputStream; 2import java.io.BufferedInputStream; 3import java.io.IOException; 4 5public class Popen { 6 public static void main(String[] args) { 7 byte[] bytes = new byte[1024]; 8 try { 9 Process perl_proc = Runtime.getRuntime().exec("./dump.pl"); 10 BufferedOutputStream ost = new BufferedOutputStream(perl_proc.getOutputStream()); 11 BufferedInputStream ist = new BufferedInputStream(perl_proc.getInputStream()); 12 ost.write("Hello world 1.\n".getBytes()); 13 ost.flush(); 14 ist.read(bytes); 15 System.out.println(new String(bytes)); 16 ost.write("Hello world 2.\n".getBytes()); 17 ost.flush(); 18 ist.read(bytes); 19 System.out.println(new String(bytes)); 20 ost.write("Hello world 3.\n".getBytes()); 21 ost.flush(); 22 ist.read(bytes); 23 System.out.println(new String(bytes)); 24 } catch (IOException e) { 25 e.printStackTrace(); 26 } 27 } 28}

投稿2016/11/22 22:11

MasashiKimura

総合スコア1150

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問