Java服务如何调用系统指令、Bat脚本记录

 更新时间:2024年06月26日 15:00:49   作者:Aikes902  
这篇文章主要介绍了Java服务如何调用系统指令、Bat脚本记录,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

前言

在项目推进过程中偶尔会涉及到调用其它组件或脚本的需求,本文重点介绍Java服务调用Bat脚本、系统指令。

调用Bat脚本

根据需求生成BAT脚本内容文本,通过文件流写入到新建的BAT文件中,然后利用ProcessBuilder执行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"; // 批处理文件的路径和名称

        // 创建一个Writer对象来写入批处理命令
        PrintWriter writer = new PrintWriter(new FileWriter(tBatFilePath));
        writer.println(cCommand); // 在批处理文件中写入命令
        writer.close(); // 关闭Writer对象

        // 执行批处理文件
        ProcessBuilder builder = new ProcessBuilder(tBatFilePath);
        // 输出指令日志
        builder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
        builder.redirectError(ProcessBuilder.Redirect.INHERIT);
        // 启动进程并后台执行批处理文件
        builder.start();

        // 删除生成的批处理文件
        File file = new File(tBatFilePath);
        if (file.delete()) {
            log.info("Batch file deleted successfully.");
        }
    }

当前模式存在两个问题需要手动处理:

1、设置了打印指令日志会导致最终服务运行的日志很多很杂,按理说Logger应该可以配置单独开一个日志文件,这块暂时还没研究到,有配置成功的同学记得评论区分享下哈。

2、执行的BAT脚本为非阻塞型,所以针对BAT脚本运行中断后的处理需要在BAT内容中实现,后面是笔者用到的BAT脚本,供大家参考。

@echo off

:: 设置重试次数和计数器变量
set max_retry=3
set retry_count=0

set remote=$remote$
set local=$local$

:retry
:: 检查重试次数是否超过最大值
if %retry_count% gtr %max_retry% (
   echo "Maximum retries exceeded. Quitting."
   goto end
)

:: 调用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%

:: 检查上一个命令的退出代码是否为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"

调用系统指令

执行系统指令还是利用ProcessBuilder,包括日志打印的套路都与BAT脚本执行一致,需要注意的一点是,针对指令中的空格分割需要通过List的集合进行拆分。

例如:

指令 rtmp-to-flv.exe -proxy 50003,50004,需要将其根据空格分为三份,分别装进List集合中,然后使用processBuilder.command方法运行即可。

    public void executeSystemCommand() {
        try {
            // 执行批处理文件
            Resource classpathResource = resourceLoader.getResource("classpath:");
            String classpathPath = classpathResource.getFile().getAbsolutePath();

            ProcessBuilder processBuilder = new ProcessBuilder();
            //定义命令内容
            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);
            //将标准输入流和错误输入流合并,通过标准输入流读取信息
            processBuilder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
            processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
            processBuilder.start(); // 启动进程并后台执行批处理文件

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

总结

利用JAVA服务运行系统指令及BAT脚本其实可以很大程度减轻JAVA的开发工总量,更容易做到功能的可插拔性,只是对开发人员的编码要求和编程思想有一些较高的要求,当然这也是作为研发的必经之路,salute。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java由浅入深学习数组的使用

    Java由浅入深学习数组的使用

    数组对于每一门编程语言来说都是重要的数据结构之一,当然不同语言对数组的实现及处理也不尽相同。Java 语言中提供的数组是用来存储固定大小的同类型元素
    2022-05-05
  • Java多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask详解

    Java多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask详解

    这篇文章主要介绍了Java多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • SpringBoot项目中建议关闭Open-EntityManager-in-view原因

    SpringBoot项目中建议关闭Open-EntityManager-in-view原因

    这篇文章主要为大家解析了在Spring Boot项目中建议关闭Open-EntityManager-in-view的原因示例分析,有需要的朋友可以借鉴参考下,希望能够有所帮助
    2022-02-02
  • Java猴子吃桃问题

    Java猴子吃桃问题

    这篇文章主要介绍了Java猴子吃桃问题,采取逆向思维的方法,从后往前推断,需要的朋友可以参考下
    2017-02-02
  • 简单了解Java synchronized关键字同步

    简单了解Java synchronized关键字同步

    这篇文章主要介绍了简单了解Java synchronized关键字同步,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • Spring中的之启动过程obtainFreshBeanFactory详解

    Spring中的之启动过程obtainFreshBeanFactory详解

    这篇文章主要介绍了Spring中的之启动过程obtainFreshBeanFactory详解,在refresh时,prepareRefresh后,马上就调用了obtainFreshBeanFactory创建beanFactory以及扫描bean信息(beanDefinition),并通过BeanDefinitionRegistry注册到容器中,需要的朋友可以参考下
    2024-02-02
  • Java使用TCP实现数据传输实例详解

    Java使用TCP实现数据传输实例详解

    这篇文章主要介绍了Java使用TCP实现数据传输实例详解的相关资料,需要的朋友可以参考下
    2017-06-06
  • Maven安装及MyEclipse中使用Maven

    Maven安装及MyEclipse中使用Maven

    这篇文章主要为大家详细介绍了Maven安装步骤,及MyEclipse中如何使用Maven,感兴趣的小伙伴们可以参考一下
    2016-07-07
  • Java IO流 文件的编码实例代码

    Java IO流 文件的编码实例代码

    本文通过实例代码给大家介绍了java io流文件编码的方法,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2017-05-05
  • 详解Java编译优化之循环展开和粗化锁

    详解Java编译优化之循环展开和粗化锁

    之前在讲JIT的时候,有提到在编译过程中的两种优化循环展开和粗化锁,今天从Assembly的角度来验证一下这两种编译优化方法,快来看看吧。
    2021-06-06

最新评论