Java服務(wù)如何調(diào)用系統(tǒng)指令、Bat腳本記錄
前言
在項(xiàng)目推進(jìn)過程中偶爾會(huì)涉及到調(diào)用其它組件或腳本的需求,本文重點(diǎn)介紹Java服務(wù)調(diào)用Bat腳本、系統(tǒng)指令。
調(diào)用Bat腳本
根據(jù)需求生成BAT腳本內(nèi)容文本,通過文件流寫入到新建的BAT文件中,然后利用ProcessBuilder執(zhí)行BAT命令,最后判斷刪除生成的BAT文件。
public void executeBatScript(String cCommand, String cBatFileName, String cBasePath) throws Exception {
//判斷路徑是否存在
File directory = new File(cBasePath);
if (!directory.exists()) {
directory.mkdir();
}
String tBatFilePath = cBasePath + cBatFileName + ".bat"; // 批處理文件的路徑和名稱
// 創(chuàng)建一個(gè)Writer對(duì)象來寫入批處理命令
PrintWriter writer = new PrintWriter(new FileWriter(tBatFilePath));
writer.println(cCommand); // 在批處理文件中寫入命令
writer.close(); // 關(guān)閉Writer對(duì)象
// 執(zhí)行批處理文件
ProcessBuilder builder = new ProcessBuilder(tBatFilePath);
// 輸出指令日志
builder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
builder.redirectError(ProcessBuilder.Redirect.INHERIT);
// 啟動(dòng)進(jìn)程并后臺(tái)執(zhí)行批處理文件
builder.start();
// 刪除生成的批處理文件
File file = new File(tBatFilePath);
if (file.delete()) {
log.info("Batch file deleted successfully.");
}
}當(dāng)前模式存在兩個(gè)問題需要手動(dòng)處理:
1、設(shè)置了打印指令日志會(huì)導(dǎo)致最終服務(wù)運(yùn)行的日志很多很雜,按理說Logger應(yīng)該可以配置單獨(dú)開一個(gè)日志文件,這塊暫時(shí)還沒研究到,有配置成功的同學(xué)記得評(píng)論區(qū)分享下哈。
2、執(zhí)行的BAT腳本為非阻塞型,所以針對(duì)BAT腳本運(yùn)行中斷后的處理需要在BAT內(nèi)容中實(shí)現(xiàn),后面是筆者用到的BAT腳本,供大家參考。
@echo off :: 設(shè)置重試次數(shù)和計(jì)數(shù)器變量 set max_retry=3 set retry_count=0 set remote=$remote$ set local=$local$ :retry :: 檢查重試次數(shù)是否超過最大值 if %retry_count% gtr %max_retry% ( echo "Maximum retries exceeded. Quitting." goto end ) :: 調(diào)用ffmpeg指令 ffmpeg -i rtmp://105if39328.51pc.cn:1935/live/0 -c copy -f flv rtmp://127.0.0.1:50001/live/aa8 ffmpeg -i %remote% -c copy -f flv %local% :: 檢查上一個(gè)命令的退出代碼是否為0(成功) if %errorlevel% neq nul ( echo "remote:%remote%. local:%local%. errorlevel:%errorlevel%. Retrying in 10 seconds...This is No.%retry_count% times Retry" :: 等待10秒后重試 ping -n 15 127.0.0.1 > nul set /a retry_count+=1 goto retry ) :end echo "Done"
調(diào)用系統(tǒng)指令
執(zhí)行系統(tǒng)指令還是利用ProcessBuilder,包括日志打印的套路都與BAT腳本執(zhí)行一致,需要注意的一點(diǎn)是,針對(duì)指令中的空格分割需要通過List的集合進(jìn)行拆分。
例如:
指令 rtmp-to-flv.exe -proxy 50003,50004,需要將其根據(jù)空格分為三份,分別裝進(jìn)List集合中,然后使用processBuilder.command方法運(yùn)行即可。
public void executeSystemCommand() {
try {
// 執(zhí)行批處理文件
Resource classpathResource = resourceLoader.getResource("classpath:");
String classpathPath = classpathResource.getFile().getAbsolutePath();
ProcessBuilder processBuilder = new ProcessBuilder();
//定義命令內(nèi)容
List<String> command = new ArrayList<>();
// rtmp-to-flv.exe -proxy 50003,50004
//
String os= System.getProperty("os.name").toLowerCase();
if (os.contains("windows")) {
command.add(classpathPath + "/rtmp-to-flv.exe");
}
else {
command.add(classpathPath + "/rtmp-to-flv");
}
command.add("-proxy");
command.add("50003,50004");
processBuilder.command(command);
//將標(biāo)準(zhǔn)輸入流和錯(cuò)誤輸入流合并,通過標(biāo)準(zhǔn)輸入流讀取信息
processBuilder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
processBuilder.start(); // 啟動(dòng)進(jìn)程并后臺(tái)執(zhí)行批處理文件
} catch (Exception e) {
e.printStackTrace();
}
}總結(jié)
利用JAVA服務(wù)運(yùn)行系統(tǒng)指令及BAT腳本其實(shí)可以很大程度減輕JAVA的開發(fā)工總量,更容易做到功能的可插拔性,只是對(duì)開發(fā)人員的編碼要求和編程思想有一些較高的要求,當(dāng)然這也是作為研發(fā)的必經(jīng)之路,salute。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java Map簡介_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
Map 接口提供三種collection 視圖,允許以鍵集、值集或鍵-值映射關(guān)系集的形式查看某個(gè)映射的內(nèi)容。本文是動(dòng)力節(jié)點(diǎn)java學(xué)院給大家整理的java map知識(shí),需要的的朋友參考下吧2017-05-05
Spring Data JDBC介紹及實(shí)現(xiàn)代碼
這篇文章主要介紹了Spring Data JDBC介紹及實(shí)現(xiàn)代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-09-09
Java使用字節(jié)流實(shí)現(xiàn)圖片音頻的復(fù)制
今天帶大家學(xué)習(xí)Java的相關(guān)知識(shí),文章圍繞著Java如何使用字節(jié)流實(shí)現(xiàn)圖片音頻的復(fù)制展開,文中有非常詳細(xì)的介紹,需要的朋友可以參考下2021-06-06
Mybatis調(diào)用SQL?Server存儲(chǔ)過程的實(shí)現(xiàn)示例
在軟件開發(fā)過程中,經(jīng)常會(huì)使用到存儲(chǔ)過程,本文就來介紹一下Mybatis調(diào)用SQL?Server存儲(chǔ)過程的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01
基于SpringBoot+Elasticsearch實(shí)現(xiàn)一套完整的搜索服務(wù)系統(tǒng)
在內(nèi)容平臺(tái)場景中,高性能、高相關(guān)性、實(shí)時(shí)可搜是搜索模塊的核心訴求,本文基于 SpringBoot 與 Elasticsearch(ES),從零實(shí)現(xiàn)一套包含索引初始化、數(shù)據(jù)同步、增量更新、關(guān)鍵詞檢索、游標(biāo)分頁的完整搜索服務(wù),需要的朋友可以參考下2026-05-05
Java超詳細(xì)講解設(shè)計(jì)模式之一的單例模式
單例模式(Singleton Pattern)是 Java 中最簡單的設(shè)計(jì)模式之一。這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式2022-03-03
Mybatis新增數(shù)據(jù)并返回主鍵id的兩種方法實(shí)現(xiàn)
本文主要介紹了Mybatis新增數(shù)據(jù)并返回主鍵id的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-02-02

