今天接到一個任務,要用第三方提供的一個jar包來進行文件的加解密,須要使用「java -jar」命令運行jar包來對文件進行加解密操做,順便記錄一下兩種實現方式java
首先了解一下Process類,顧名思義,這個類叫進程類,封裝了一個進程(即一個執行程序)。app
官方解釋:
Process類提供了執行進程輸入、執行輸出到進程、等待進程完成、檢查進程退出狀態以及銷燬(殺死)進程的方法。ui
提供了6個抽象方法this
public abstract OutputStream getOutputStream(); 返回鏈接到子進程正常輸入的輸出流加密
public abstract InputStream getInputStream(); 返回鏈接到子進程正常輸出的輸入流線程
public abstract InputStream getErrorStream(); 返回鏈接到子進程錯誤輸出的輸入流code
public abstract int waitFor() throws InterruptedException; 使當前線程在必要時等待,直到此Process對象表示的Process終止對象
public abstract int exitValue(); 此Process對象表示的子流程的退出值。 按照慣例,值0表示正常終止。拋出IllegalThreadStateException的話表示此Process對象表示的子Process還沒有終止進程
public abstract void destroy(); 殺死子進程。 此Process對象表示的子流程是否被強制終止取決於實現ci
1.8版本後新增如下三個公共方法
public boolean waitFor(long timeout, TimeUnit unit) throws InterruptedException{ long startTime = System.nanoTime(); long rem = unit.toNanos(timeout); do { try { exitValue(); return true; } catch(IllegalThreadStateException ex) { if (rem > 0) Thread.sleep( Math.min(TimeUnit.NANOSECONDS.toMillis(rem) + 1, 100)); } rem = unit.toNanos(timeout) - (System.nanoTime() - startTime); } while (rem > 0); return false; } public Process destroyForcibly() { destroy(); return this; } public boolean isAlive() { try { exitValue(); return false; } catch(IllegalThreadStateException e) { return true; } } }
回到原來的話題,執行「java -jar"命令運行jar包進行加解密。我先是用Runtime.exec() 方法建立一個本機進程,並返回 Process 子類的一個實例的方式來實現,來看下代碼:
String command = "java -jar D:/work/si-tech/project/cbn/lib/acctmgr-application/jfycrpto.jar DEC 8613052000078705_001_003_20200115_689814_I.TXT"; try{ Process p = Runtime.getRuntime().exec(command); InputStream is = p.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); String outInfo; while ((outInfo = reader.readLine()) != null) { System.out.println(outInfo); } p.waitFor(); // 等待process子進程終止 return p.exitValue() == 0; }catch (Exception e){ log.error("{}{}失敗",fileName, encrypt ? "加密" : "解密"); return false; }
後來瞭解到,從 1.5 開始, ProcessBuilder.start()是建立Process的首選方式,因而最終改爲以下方式:
/* 命令用List存儲 */ String[] commandSplit = command.split(" "); List<String> lcommand = new ArrayList<>(Arrays.asList(commandSplit)); ProcessBuilder processBuilder = new ProcessBuilder(lcommand); processBuilder.redirectErrorStream(true); // 此對象的start()方法隨後啓動的子進程生成的任何錯誤輸出都將與標準輸出合併,以即可以使用Process.getInputStream()方法讀取二者 try{ Process process = processBuilder.start(); InputStream is = process.getInputStream(); BufferedReader bs = new BufferedReader(new InputStreamReader(is)); process.waitFor(); // 等待process子進程終止 String line = null; while ((line = bs.readLine()) != null) { System.out.println(line); } return process.exitValue() == 0; }catch (Exception e){ log.error("{}{}失敗",fileName, encrypt ? "加密" : "解密"); return false; }