外部コマンドを使用しない標準出力の取得方法

このQ&Aのポイント
  • javaのプログラム内で標準出力を取得する方法を教えてください。
  • 標準出力をするメソッドを呼び出した後に、そのメソッドが標準出力した内容を取得したいです。
  • 具体的な実装方法を教えてください。
回答を見る
  • ベストアンサー

外部コマンドを使用しない標準出力の取得方法を教えて下さい

外部コマンドを使用しない標準出力の取得方法を教えて下さい いつもお世話になっています。 javaのプログラム内で、その直前の標準出力を取得する方法がわかりません。「標準出力 取得」などで検索しても、外部プロセスがらみ(Runtime.getRuntime().exec(xxx)のprocessからストリームを取得など)の事ばかりがヒットしてしまいます。 やりたい事はもっと単純で、標準出力をするメソッドを呼び出した後に、そのメソッドが標準出力した内容を取得したいのです。 以下のコードのコメントの箇所の、具体的な実装方法を知りたいのです。この例では簡単のために、標準出力するメソッドを同一クラス内のメソッドとしていますが、本当は別のクラスのメソッドで、もちろん標準出力の内容は実行時までわかりません。 public class hello {   public static void main (String[] args) {     sub();     // sub()で標準出力した内容をここで取得したい!   }   private static void sub(){     System.out.println("Hello World !!");   } }

  • aneja
  • お礼率93% (379/405)
  • Java
  • 回答数6
  • ありがとう数12

質問者が選んだベストアンサー

  • ベストアンサー
  • askaaska
  • ベストアンサー率35% (1455/4149)
回答No.5

単純に考えると   static String logc = null;//キャッシュ用変数   private static void sub(){     logc = "Hello World !!";     System.out.println(logc);   } こうしてあげれば   public static void main (String[] args) {     sub();     // sub()で標準出力した内容をここで取得したい!     // logcから取得できる   } となるのは分かるかしら? System.out.printlnの記述が一箇所にまとまっていれば こんなやり方もOKよね。 でもあっちこっちにある場合は System.out.printlnの内部で System.out.printlnとキャッシュ処理を用意してあげなくちゃダメね。 たとえばMyPrintStreamというPrintStreamクラスを継承したクラスを作成して println(引数)メソッド内で super.println(引数); logc=引数; をしてあげる。 あとはMyPrintStreamにget直前ログメソッドを作って logcをリターンしてあげればいいわ。

aneja
質問者

お礼

しょうもない間違いをたくさんしつつ、ようやく動きました…。少しだけ、継承の利用方法がわかりました。本当にありがとうございました。

aneja
質問者

補足

お礼が遅くなって、どうもすみません。それから再度のご登場、どうもありがとうございます。教えていただいた方法でコーディングして確認しようとしておりますが、コンパイルが通らなかったりランタイムエラーが出たりで、てこずっております…。(お礼欄に書かずに補足欄に書いてるのは、お礼欄に追記できないからです。)

その他の回答 (5)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.6

世の中には TeePrintStream なんてものを作ってる人もいます.

aneja
質問者

お礼

いつもお礼が遅くなり、申し訳ありません。何度もご登場いただいて、本当にありがとうございます。TeePrintStreamを調べてみました。今後に応用できそうです、どうもありがとうございました。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

まず確認だけど, 「標準出力」というのは「System.out への出力」と思っていい? あと, ひょっとして「標準出力に出るはずだったものを取得する」だけじゃなくって「標準出力に出しつつ, その内容を取得する」ってこと? いずれにしても, 原理的には可能です. 「2つの PrintStream に同時に出力する」ものが必要なんだけど, これくらいのことは当然考える人はいるようで, 調べればでてくる. それさえあれば, setOut で System.out を変更すればいいだけ.

aneja
質問者

お礼

お礼が遅くなり、申し訳ありません。ご回答どうもありがとうございました。 >まず確認だけど, 「標準出力」というのは「System.out への出力」と思っていい? 具体的には、コンソール画面への出力という意味です。Windowsでは、cmd.exeをたたいた時に出る黒い画面のことです。 >あと, ひょっとして「標準出力に出るはずだったものを取得する」だけじゃなくって「標準出力に出しつつ, その内容を取得する」ってこと? はい。そのひょっとしてです。想定は、Javaプログラムから、コンソールに結果を出力するAPIをたたいた後、その出力結果を取り出して次の処理に使うという使い方です。そのAPIは単なるライブラリなので、Runtime.execとかを使うんじゃないんですよ…。 でも、原理的に可能とおっしゃっていただいて、安心しました。ちょっと調べ方が甘いようでまだ見つけられていませんが、やっぱりキーはsetOutなんですね。 どうもありがとうございました。

回答No.3

 Bruce Eckel, "Thinking in Java (4th Edition)" (Prentice Hall, 2006) によると、p.942~p.943に、次のようにあります。  The Java System class allows you to redirect the standard input, output, and error I/O streams using simple static method calls:  setIn(InputStream)  setOut(PrintStream)  setErr(PrintStream)  Redirecting output is especially useful if you suddenly start creating a large amount of output on your screen, and it’s scrolling past faster than you can read it.  Redirecting input is valuable for a command-line program in which you want to test a particular user-input sequence repeatedly.  Here’s a simple example that shows the use of these methods: //: c12:Redirecting.java // Demonstrates standard I/O redirection. import java.io.*; public class Redirecting { // Throw exceptions to console: public static void main(String[] args) throws IOException { PrintStream console = System.out; BufferedInputStream in = new BufferedInputStream( new FileInputStream("Redirecting.java")); PrintStream out = new PrintStream( new BufferedOutputStream( new FileOutputStream("test.out"))); System.setIn(in); System.setOut(out); System.setErr(out); BufferedReader br = new BufferedReader( new InputStreamReader(System.in)); String s; while((s = br.readLine()) != null) System.out.println(s); out.close(); // Remember this! System.setOut(console); } }

aneja
質問者

お礼

ご丁寧なご回答、どうもありがとうございます。例示下さったコードのように、自由に標準入出力先を変えられるということは理解できました。この例のinという入力ファイルストリーム(っていうんでしょうか)をデフォルトの標準出力に変えて、outという出力ファイルストリームをオンメモリの文字列に書き出してやれば、できるということなんでしょうか。(情けないことに、今はそのように書き換えるスキルはありませんが…) ただ、以下の2点がよくわかりません。javaの初心者には超難問に感じています。 1.標準出力先として、従来のコンソールに加えて別のバッファ(Stringとかを想定)も設定できたとして、それを別クラスのメソッドにどうやって伝えればよいのか?引数などで与えてやればできるのか? 2.別クラスのメソッドは、やはり本来のコンソール等に出力することが前提で、そのメソッドをコールした次のステートメントで「1つ前のステートメントで出した標準出力だけを取り込みたい」ということはできるのか?#2の方の仰るように、不可能なのか?別クラスのメソッド内でテンポラリファイルにもこっそり出力し、テンポラリファイルを読み込むというような方法でしか無理なのか? とりとめの無い内容で申し訳ありませんが、どなたかもうしばらくお付き合いいただけるとうれしいです。

  • askaaska
  • ベストアンサー率35% (1455/4149)
回答No.2

無理ね。 保持していないし。 どうしてもやりたいのなら 自分で保持する仕組みを用意するしかないわ。

aneja
質問者

お礼

ご回答どうもありがとうございました。自分で保持する仕組みというのは、#1の方へのお礼に書いたようなことを自分でゴリゴリ実装するしかないということでしょうか。標準出力に出すものを前もって保存するような仕組み…情けないですが、まったく分かりません…。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

へ~, setOut なんてあるんだ....

aneja
質問者

お礼

早速のご回答、ありがとうございます。お礼が遅くなり、申し訳ありません。 教えて下さったのは、System.setOutのことなんですよね。API仕様には、標準出力ストリームの再割り当てと書かれていますね。恥ずかしながら、javaはまだ始めて間も無いので、今具体的に「こうすればいい」というのがわからないのですが、理論上は「できる」ということなんでしょうか。ただ、別クラスのメソッドに、「標準出力先はコンソールだけど、オンメモリでも保存しておいて」という指令が出せるものなのでしょうか?的外れなことを言っていますでしょうか。

関連するQ&A

  • Runtime クラスのexecメソッドについて

    javaで、Runtimeのexec()メソッドを使って、出てきた内容をJTextAreaに出力したいと思っています。つまり、JTextAreaをコマンドプロンプト風にしたいと思っています。しかし、exec()メソッドの戻り値である、Processクラスがいまいちよくわかりません。仕様書(日本語訳)を読んでもProcessクラスのgetInputStream()メソッドやgetOutputStream()メソッドの説明がいまいちピンときません。 try{ Process process = Runtime.getRuntime().exec("hogehoge"); /*---------------------------------------------------------*/ ここで、いかにしてJTextAreaに出力するのかわかりません /*---------------------------------------------------------*/ }catch(Exception e){ } どうか、わかる方よろしくお願いします。

    • ベストアンサー
    • Java
  • Javaプログラムから外部コマンドを呼び出す

    String com = "ls -l"; Process pro = Runtime.getRuntime().exec(com); 上記のようにして、外部コマンドを実行しています。 この方法を使用すると投げたコマンドが終了してしまうまで、後の処理が行われません。 バックグラウンド処理を行いたかったので、 String com = "ls -l &"; Process pro = Runtime.getRuntime().exec(com); としてみましたが、結果は変わりませんでした。 何か別の指定方法が存在するのでしょうか。 ご存知の方、ぜひ教えてください。

    • ベストアンサー
    • Java
  • 外部jarの標準出力を取得できますか?

    ClassLoaderで外部jarのクラスをロードし、実行するプログラムを作りました。 SimpleOutputは、単に渡された引数を標準出力に出すだけのものです。 この値を取得してGUI上に表示させたいのですが、取得する方法をご教授ください。 System.out.println("Load class"); URL[] urls = { file.toURI().toURL() }; ClassLoader loader = URLClassLoader.newInstance(urls); Class<?> cls = loader.loadClass("SimpleOutput"); System.out.println(cls); Object obj = cls.newInstance(); Method method = cls.getMethod("main", String[].class); String[] av = {"test"}; method.invoke(obj, new Object[]{av});

    • ベストアンサー
    • Java
  • abstract と static を一緒に付けることはある?

    抽象クラスの抽象メソッドにstaticを付ける(abstract と static をメソッドに一緒に付ける)ことはありますか? 例えば、 abstract class Super {  static abstract void meth(); } class Sub extends Super {  static void meth() {   System.out.print("hello");  } } として、mainの中に  Sub.meth(); を書いてみたのですが、普通にコンパイルは通りhelloが出力されます。 staticの意味を考えると、こういうことをするのは意味がないと思うのですが、独学なので身近に聞ける人もいません。 御教授よろしくお願いします。

  • Javaで外部コマンドの実行した結果の取得

    Javaで外部コマンドを実行してその結果を取得しようとしてEclipse上で 下記サンプルを作成しました。ここで不思議なことが起きました。 下記を実行すると System.out.println(in.ready()) の部分でfalseが返り処理がwhileループの中に入らない状態です。 しかし、System.out.println(in.ready())の部分にブレークポイントを付けて1行ずつ実行していくと trueが返りwhileループの中の結果を読み取る処理にたどり着きます。 これはどういうことでしょうか。 public class Test { public static void main(String[] args) { String command = "hostname"; try { Process process = Runtime.getRuntime().exec(command); BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream())); System.out.println(in.ready());             while(in.ready()) { } in.close(); } catch(Exception e) { e.printStackTrace(); } } }

    • ベストアンサー
    • Java
  • 外部コマンドを実行する方法

    sdk 1.4.2_08 OS WindowsXp try{ Process process = Runtime.getRuntime().exec(...); }catch(IOException e){} を使用して,コマンドを実行しようとしています.しかし,IOExceptionとなってしまいます. exec(...) に記述してある内容をコピーして,コマンドラインから実行できることは確認しましたし,パスも大丈夫でした. また空白が認識されない場合があることから, String cmd[] = {"コマンド","引数1","引数2"}; Process process = Runtime.getRuntime().exec(cmd); と行ってもダメでした. また,ためしにこのコンパイル済みのclassファイルをLinuxで動作させたところ,正常の動作できることがが確認できました.(windowsとLinuxに同じ名前のコマンドがあるのです.また,Linuxは fedora core4 です.) Windows上のコマンドに問題があるようなのですが,何か原因となる要因が,他にもありそうでしたらアドバイスお願いいたします.

    • ベストアンサー
    • Java
  • ディレクトリを変更して外部コマンド実行

    いつもお世話になってます。 Runtime.execを使用してディレクトリ情報を txtファイルに出力しようとしているのですが、 現在のカレントディレクトリのものは出力できるのですが、 例えば、dドライブのtestフォルダに移動して 出力というのをどうやればいいのかわかりません。 ネットでいろいろ調べてみたものの、どうしてもわかりませんでした。 よろしくお願いします。 下記はカレントディレクトリの情報をそのままtxtファイルに出力したものです。 String command2 = "cmd /c dir > d:\\testest.txt"; Process process = Runtime.getRuntime().exec(command2);

    • ベストアンサー
    • Java
  • 外部コマンドの実行について

    ・Actionクラス public ActionForward Batch(     ActionMapping objActMapping,     ActionForm objActFrm,     HttpServletRequest objHttpRequest,     HttpServletResponse objHttpResponse)     throws Exception {         ActionForward objActFwd = null;         TestForm objTestForm = null;         try {             Runtime runtime = Runtime.getRuntime();             Process process = runtime.exec("c:/Batch/Batch.bat");             objActFwd = objActMapping.findForward("success");           }           catch (Exception e) {             e.printStackTrace();             throw e;           }         return objActFwd; } 以上のActionクラスをJSPからStrutusを介し実行しておりますが バッチファイルが実行されません。 batch.bat単体では実行可能です。 ご教授お願いいたします。 環境:WindowsXP j2sdk1.4.1 Jboss-3.2.3

    • ベストアンサー
    • Java
  • javaアプリケーションからコマンド実行結果の取得

    javaアプリケーションからcatコマンドを実行し、その結果を取得したいのですが、うまくいきません。runtime.exec()実行中にエラーとなります。 String cmd = "cat error.log; echo $status"; Runtime runtime = Runtime.getRuntime; Process process = runtime.exec(cmd); rshを使うとOKです。 "rsh localhost cat error.log; echo $status" shを使うとNGです。 "sh -c cat error.log; echo $status" "sh -c \"cat error.log\"; echo $status" ターミナルからは上記で内容取得、および、結果取得はできるのですが。 環境は、UNIX JDK1.2.1です。 よろしくお願いします。

  • PHP5の外部コマンド実行で、バッチファイルのエラーレベル値と標準出力(標準エラー?)の3つを取得できる関数はありますか?

    PHP5のWindows版を使っています。 外部コマンドを実行して、Windowsのバッチファイルのエラーレベル値と標準出力(標準エラー?)の3つを取得できる関数はありますか? test.cmdの中味 echo 標準出力内容です。 echo バッチファイルで標準エラー出力はわかりませんが exit /b 2 list ($ret, $stdout, $stderr) = 何か関数("test.cmd") echo $ret; // 2 echo $stdout; // 標準出力内容です。\nバッチファイルで標準エラー出力はわかりませんが echo $stderr; // ???? よろしくお願い致します。

    • ベストアンサー
    • PHP

専門家に質問してみよう