2017-01-03 12 views
1

Runtime execProcessを使用して、Javaアプリケーションでシステムコマンドを実行しようとしました。デモンストレーションのための簡単なプログラムを作成しました。この例のコマンドはjavacです。これはJavaプログラムをコンパイルするだけです。アプリケーションを使用して、コンパイルするファイルを選択し、後で保存する出力フォルダを選択するだけです。ここでJavaアプリケーションでシステムコマンドを実行

は、完全なプログラムコードです:

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.BufferedReader; 
import java.io.File; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import javax.swing.JButton; 
import javax.swing.JFileChooser; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class Test { 

    private static JFileChooser jFileChooser1, jFileChooser2; 

    public static void main(String[] args) { 

     JFrame jFrame = new JFrame(); 
     jFrame.setSize(238, 62); 
     jFrame.setResizable(false); 
     jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     JPanel jPanel = new JPanel(); 
     jPanel.setLayout(null); 

     jFileChooser1 = new JFileChooser(); 
     jFileChooser2 = new JFileChooser(); 


     JButton jButton1 = new JButton("File"); 
     jButton1.setBounds(1, 1, 70, 25); 
     jButton1.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       jFileChooser1.setCurrentDirectory(new File(System.getProperty("user.dir"))); 
       jFileChooser1.showOpenDialog(jFrame); 
      } 
     }); 
     jPanel.add(jButton1); 


     JButton jButton2 = new JButton("Folder"); 
     jButton2.setBounds(75, 1, 70, 25); 
     jButton2.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       jFileChooser2.setCurrentDirectory(new File(System.getProperty("user.dir"))); 
       jFileChooser2.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); 
       jFileChooser2.showOpenDialog(jFrame); 
      } 
     }); 
     jPanel.add(jButton2); 


     JButton jButton3 = new JButton("Compile"); 
     jButton3.setBounds(149, 1, 80, 25); 
     jButton3.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 

       File selectedFile = jFileChooser1.getSelectedFile(); 
       File selectedFolder = jFileChooser2.getSelectedFile(); 

       String s = null; 

       try { 
        Process p = Runtime.getRuntime().exec("javac -d " +selectedFolder+ " " +selectedFile); 

        BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream())); 
        BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream())); 

        while ((s = stdInput.readLine()) != null) { 
         System.out.println(s); 
        } 

        while ((s = stdError.readLine()) != null) { 
         System.out.println(s); 
        } 
       } catch (IOException ex) { 
        ex.printStackTrace(); 
       } 
      } 
     }); 
     jPanel.add(jButton3); 


     jFrame.add(jPanel); 
     jFrame.setVisible(true); 
    } 
} 

しかし、私が開発しています実際のアプリケーションでは、私が実行しようとしているシステムのコマンドは、私はアプリケーション内で維持したいバイナリプログラム(ローカルが必要ですリソースファイル)。たとえば、パッケージはassetsです。だから、リソースファイルにアクセスするために、私はこのコードを使用します

URL binary = Test.class.getClassLoader().getResource("assets/binary.bin"); 

をして、コマンドの使用例/構文のようなものです:

"command -options " +binary+ " " +selectedFile+ " " +selectedFolder+ " 

、プログラム中:

... 
try { 
    URL binary = Test.class.getClassLoader().getResource("assets/binary.bin"); 
    Process p = Runtime.getRuntime().exec("command -options " +binary+ " " +selectedFile+ " " +selectedFolder+ "); 
    ... 
} 

IDEで試してみるとエラーが表示されます:

Error: Unable to access jarfile file:/D:/Projects/Java/Test/build/classes/assets/binary.bin 

これも可能ですか?どうすればこれを達成できますか?どんな助けもありがとう!

+0

ProcessBuilderとそれに関連するクラスを使用し、実行時は決して使用しないでください:) –

答えて

0

ではありません。

オペレーティングシステムに電話をかけて、どこかの実行可能ファイルを実行するようにしたいとします。

しかし、どこかにはオペレーティングシステムがアクセスできるものでなければなりません。言い換えれば、ローカルファイルシステムに存在するものなどです。

JARからバイナリファイルの内容を取得することで回避できます。ローカルの一時ディレクトリに書き込んでください。

したがって、内部リソースを指す代わりに、プログラムは最初にそのバイナリの "temp"バージョンを作成する必要があります。 ProcessBuilder(それは2017です; Runtime.exec()については忘れてください);後でその一時ファイルを最後に削除します。

+0

大丈夫、2017の部分が大好きです。ありがとうございました!私はまだプログラミングの初心者です(質問にそれを含めるのを忘れてしまった)。私はそれを探しに行くでしょう。もう一度ありがとう:) –

+0

記録のために:もちろんProcessBuilderを使用して、そのようなことを行う "最先端の"方法です。それはあなたの中心的な質問に実際には影響しません。 Runtime.execやProcessBuilderを使用すると違いはありません。結局、クラスパスのどこかのリソースとして存在するバイナリを実行することはできません(いくつかのJARファイルにラップアップされています)。 – GhostCat

+0

ええ、私は今それを得る。どうもありがとうございます! :) –

関連する問題