熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> JSP教程 >> 正文

詳細講解怎樣在Java中運行其它應用程序

2013-11-15 11:49:51  來源: JSP教程 

  import javaio*;
  
  public class CommandWrapper
  {
  Process process;
  Thread in;
  Thread out;
  public CommandWrapper(Process process)
  {
  thisprocess = process;
  final InputStream inputStream =
  processgetInputStream();
  //final BufferedReader
  r=new BufferedReader
  (new InputStreamReader(inputStream));
  final byte[] buffer = new byte[];
  out = new Thread()
  {
  //String line;
  int lineNumber=;
  public void run()
  {
  try {
  while (true)
  {
  int count = inputStreamread(buffer);
  Systemoutprintln
  (lineNumber+:+new String
  (buffer count));
  //line=rreadLine();
  //Systemoutprintln
  (lineNumber+:+line);
  lineNumber++;
  }
  }
  catch (Exception e)
  {
  
  }
  }
  };
  final BufferedReader reader =
  new BufferedReader
  (new InputStreamReader(Systemin));
  final OutputStream
  outputStream = processgetOutputStream();
  in = new Thread()
  {
  String line;
  public void run()
  {
  try
  {
  while (true)
  {
  outputStreamwrite(
  (readerreadLine()+\n)getBytes());
  outputStreamflush();
  }
  }
  catch (Exception e)
  {
  
  }
  }
  };
  }
  
  public void startIn()
  {
  instart();
  }
  
  public void startOut()
  {
  outstart();
  }
  
  public void interruptIn()
  {
  ininterrupt();
  }
  
  public void interruptOut()
  {
  outinterrupt();
  }
  
  public static void main
  (String[] args)
  {
  try
  {
  CommandWrapper command
  = new CommandWrapper
  (RuntimegetRuntime()exec(nativeascii));
  commandstartIn();
  commandstartOut();
  }
  catch (Exception e)
  {
  eprintStackTrace();
  }
  }
  
  }
  
  我以nativeascii為范例程序和網友給我的那個程序做了對比發現如下幾個在處理這個問題時需要注意的地方
  
  由於不知道目標程序的輸入輸出順序因此只能建立兩個單獨的線程分別處理輸入和輸出這樣輸入和輸出就不會阻塞了但是有些目標程序要求有特定的輸入輸出順序而經過這個類封裝的結果是在任何狀態下都可以輸入程序的任何輸出也會被馬上反映出來這是構造通用類的第一個問題
  
  不能直接使用I/O重定向在最開始的時候我是考慮直接使用I/O重定向的但是實際的情況是Process的I/O的定義剛好和我的預想相反我們從Process取得的InputStream實際上是它的輸出而取得的OutputStream是它的輸入這樣就無法進行I/O重定向了必須我們進行編碼來讀取程序的輸出和寫入控制台的輸入(這裡的I/O重定向是指想將它的I/O直接重定向到系統的I/O)
  
  寫入控制台的輸入
  
  outputStreamwrite(
  (readerreadLine()+\n)getBytes());
  outputStreamflush();
  
  這裡有兩個問題值得注意第一個是我們在控制台輸入一行數據以後按下回車那麼語句readerreadLine()可以正確的得到你的輸入為什麼要加那個換行符呢?這是在測試的時候發現的問題在以nativeascii作為例子的時候發現不加這個的話它不能得到控制台的輸入但是我在替那位網友解決的問題的時候他的程序則沒有這個問題
  
  因此猜想可能是因為有的程序要求讀取的一整行的數據(例如nativeascii)而大部分的命令行程序在編碼的時候讀取的是整數這樣的值或者其他類型的值他們是以空格或者其他的字符分隔的因此就不需要那個額外的換行符(例如那位網友的程序讀取的是一元二次方程的三個系數)
  
  另外一個問題就是flush方法的使用在最開始的時候沒有想到要這樣刷新進去無論是否加換行符外部程序都無法讀取寫入的輸入後來才想到要調用一下這個方法這個也是在我們輸出的時候應該注意的一個問題有些需要馬上反應出來的輸出一般都在寫入以後要調用它否則輸出/輸入不能馬上反應出來
  
  對於程序的輸出最開始我是構造的一個BufferedReader想以行為單位輸出對於那位網友的程序結果證明不是很好用但是以nativeascii作為例子運行又沒有問題這個估計和外部程序的代碼也有關系如果外部程序沒有輸出換行符可能使用BufferedReader就會有問題但是通過直接讀取輸出就沒有問題了另外需要注意的就是
  
  Systemoutprintln
  (lineNumber+:+new String
  (buffer count));
  
  中嚴格來說應該是
  
  Systemoutprintln
  (lineNumber+:+new String
  (buffer count));
  
  之所以減一是因為讀取輸入的時候人為的多加了一個換行符如果這個地方不減一就會多輸出一個空行
  
  基於以上的種種原因要構造一個執行外部程序的包裝器類不太好辦特別是文章中提到的幾個問題有時間和興趣的朋友可以做一下測試看看以上的問題和猜測是否正確
  
  另外附上一段源代碼是一個fortran的程序
  
  implicit none
  real abc
  real d
  real rootroot
  print*請輸入一元二次方程
  的系數abc:
  read(**) abc
  d=b***a*c
  if(d>=) then
  root=(b+sqrt(d))/(*a)
  root=(bsqrt(d))/(*a)
  print*root=root
  print*root=root
  else
  print*一元二次方程沒有實根!
  end if
  pause
  end
From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19704.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.