iis服务器助手广告广告
返回顶部
首页 > 资讯 > 操作系统 >如何使用Java调用Linux系统命令
  • 726
分享到

如何使用Java调用Linux系统命令

2024-04-02 19:04:59 726人浏览 安东尼
摘要

目录Java调用linux系统命令java执行Linux命令,支持通配符(*)Java调用Linux系统命令 有时候,我们在使用Java做一些操作时,可能性能上并不能达到我们满意的效

Java调用Linux系统命令

有时候,我们在使用Java做一些操作时,可能性能上并不能达到我们满意的效果,就拿最近工作中的遇到的一个场景来说,需要对大量的小文件进行合并成一个大文件。

最开始的想法是使用Java做文件操作,遍历所有小文件然后往一个文件写(可以做成并发写),但是发现操作过程中遇到个问题,写一千多个小文件在本机windows下需要花费几十秒的时间,即使在Linux环境下高配置的机器也需要将近十秒,这明显对接口的响应时间产生重要影响。这块怎么优化下呢?

我们都知道在Linux下可以进行大文件的分割和合并,分别采用split和cat命令,于是做了个实验,在Linux下对相同的一个1G文件进行切割成1000个小文件,然后对这一千多个小文件进行合并。效果是惊人的!!!竟然瞬间就能合成完成了!这更加让我坚定了应该使用系统命令进行批量小文件进行合并的想法。

我们这里封装一个类,用来调用系统命令,然后得到系统调用的返回结果。

我们先封装了一个返回结果类:


package com.majing.learning.fileupload.common.process;
 
public class ProcessResult {
 private boolean success = false;
 private String errORMessage;
 private String outputMessage;
 public boolean isSuccess() {
  return success;
 }
 public void setSuccess(boolean success) {
  this.success = success;
 }
 public String getErrorMessage() {
  return errorMessage;
 }
 public void setErrorMessage(String errorMessage) {
  this.errorMessage = errorMessage;
 }
 public String getOutputMessage() {
  return outputMessage;
 }
 public void setOutputMessage(String outputMessage) {
  this.outputMessage = outputMessage;
 }
 
}

接着我们给出封装的系统调用实现类:


package com.majing.learning.fileupload.common.process;
 
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
 
import org.apache.commons.lang3.StringUtils;
 
public class CommandUtils {
 
 public static ProcessResult runCmdTest(ExecutorService executorService, String command) throws IOException, InterruptedException {
  StringBuilder queryInputResult = new StringBuilder();
  StringBuilder queryErroInputResult = new StringBuilder();
  ProcessResult processResult = new ProcessResult();
  String[] cmd = { "/bin/sh", "-c", command};
  Process pro = Runtime.getRuntime().exec(cmd);
  CountDownLatch lock = new CountDownLatch(2);
  executorService.submit(new ProcessCheckTask(queryInputResult, lock, pro.getInputStream()));
  executorService.submit(new ProcessCheckTask(queryErroInputResult, lock, pro.getErrorStream()));
  boolean done = false;
  while (!done) {
   lock.await();
   done = true;
  }
  processResult.setOutputMessage(queryInputResult.toString());
  processResult.setErrorMessage(queryErroInputResult.toString());
  processResult.setSuccess(StringUtils.isBlank(processResult.getErrorMessage()));
  return processResult;
 }
}

其中ProcessCheckTask类如下:


package com.majing.learning.fileupload.common.process;
 
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.concurrent.CountDownLatch;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import com.majing.learning.fileupload.common.ConstValues;
 
public class ProcessCheckTask implements Runnable {
 
 private static Logger logger = LoggerFactory.getLogger(ProcessCheckTask.class);
 
 
 private CountDownLatch lock;
 
 
 private InputStream inputStream;
 
 
 private StringBuilder queryInputResult;
 
 public ProcessCheckTask(StringBuilder queryInputResult, CountDownLatch lock, InputStream inputStream) {
  super();
  this.lock = lock;
  this.inputStream = inputStream;
  this.queryInputResult = queryInputResult;
 }
 
 @Override
 public void run() {
  try {
   BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream));
   String line = null;
   while ((line = bf.readLine()) != null && line.length() > 0) {
    queryInputResult.append(line).append("\n");
   }
  } catch (Exception e) {
   logger.error(ConstValues.EXCEPTION_OCCURED, e);
  } finally {
   lock.countDown();
  }
 }
}

上面是一个简单实现,但是可能会存在一个问题,那就是执行系统命令的时间如果本身比较长,如果不想一直等待到系统命令执行完,而是在一段时间没有返回就直接认为失败,所以需要增加过期时间的考虑。这里我借助于Future框架,将上面的调用系统命令的方法封装成一个Callable对象。


package com.majing.learning.fileupload.common.process;
 
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
 
public class CommandTask implements Callable<ProcessResult>{
 
 private ExecutorService executorService;
 
 private String command;
 
 public CommandTask(ExecutorService executorService, String command){
  this.executorService = executorService;
  this.command = command;
 }
 
 @Override
 public ProcessResult call() throws Exception {
  return CommandUtils.runCmdTest(executorService, command);
 }
 
}

然后在上面的CommandUtils的基础上再封装一层变成CommandHelper,具体实现如下:


package com.majing.learning.fileupload.common.process; 
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; 
import com.majing.learning.fileupload.common.ConstValues;
 
 public class CommandHelper {
 private static Logger logger = LoggerFactory.getLogger(CommandHelper.class);
 private static ExecutorService executorService=Executors.newFixedThreadPool(50);
 private static long default_timeout = 8000;
 public static ProcessResult process(String command){
  return process(command, default_timeout, TimeUnit.MILLISECONDS);
 }
 
 public static ProcessResult process(String command, long timeout, TimeUnit unit){
  CommandTask commandTask = new CommandTask(executorService, command);
  Future<ProcessResult> processResult = executorService.submit(commandTask);
  ProcessResult result = null;
  try{
   result = processResult.get(timeout, unit);
  }catch(Exception e){
   logger.error(ConstValues.EXCEPTION_OCCURED, e);
  }
  return result;
 } 
}

至此,我们在需要调用系统命令时直接调用CommandHelper.process(command)就可以了,然后拿到返回结果ProcessResult。我也是自己做个记录,有需要的朋友可以直接拿去用。

顺便说一句,采用封装的这个类在完成上面相同的任务时,时间都在相同的机器上,耗时从原来的10s瞬间减少至200ms以内,由此可见,在适当的场景调用系统命令是多么重要啊。

java执行Linux命令,支持通配符(*)

java执行linux或者windows命令,这个需求比较常见。

但是若使用 Runtime.getRuntime().exec(cmd); 会发现,若cmd中含有通配符,则无法执行,如cp /dira/*.txt /dirb

可用如下方式执行:


String[] cmdArr = new String[3];
        cmdArr[0] = "/bin/sh";
        cmdArr[1] = "-c";
        cmdArr[2] = command;
process = Runtime.getRuntime().exec(cmdArr);

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: 如何使用Java调用Linux系统命令

本文链接: https://www.lsjlt.com/news/156246.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何使用Java调用Linux系统命令
    目录Java调用Linux系统命令java执行Linux命令,支持通配符(*)Java调用Linux系统命令 有时候,我们在使用Java做一些操作时,可能性能上并不能达到我们满意的效...
    99+
    2024-04-02
  • Python调用linux系统命令--使
    在python 中调用系统命令,如果使用subprocess.Popen() 模块,按照命令参数的的形式,可以分两种:把命令当作字符串传给subprocess.Popen() 把命令保存到一个元组,list 的序列,再传给subproces...
    99+
    2023-01-31
    命令 系统 Python
  • python调用linux系统命令
    python3脚本代码如下# !/usr/bin/python# -.- coding: utf-8 -.-__author__ = 'www.py3study.com'import getpassimport osclas...
    99+
    2023-01-30
    命令 系统 python
  • linux系统sudo命令如何使用
    今天小编给大家分享一下linux系统sudo命令如何使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来...
    99+
    2023-05-25
    linux sudo
  • Linux系统pwd命令如何使用
    这篇文章将为大家详细讲解有关Linux系统pwd命令如何使用,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。pwd是Print Working Directory的缩写,其功能是显示当前所在工...
    99+
    2023-06-28
  • linux系统如何使用netstat命令
    这篇文章主要为大家展示了“linux系统如何使用netstat命令”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“linux系统如何使用netstat命令”这篇文章吧。Netstat 命令用于显示...
    99+
    2023-06-27
  • Linux系统中clock命令如何使用
    这期内容当中小编将会给大家带来有关Linux系统中clock命令如何使用,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。clock 命令:设置或者显示硬件时间的近似值必要参数--adjust 自动调整硬件时...
    99+
    2023-06-12
  • Linux系统中install命令如何使用
    Linux系统中install命令如何使用,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。用法:install [选项]... [-T] 源文件 目标文件 或:install...
    99+
    2023-06-12
  • Linux系统中如何使用ps命令
    小编给大家分享一下Linux系统中如何使用ps命令,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Linux中的ps命令是Process Status的缩写。ps命...
    99+
    2023-06-27
  • linux系统中如何使用Netstat命令
    小编给大家分享一下linux系统中如何使用Netstat命令,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Netstat 命令用于显示各种网络相关信息,如网络连接...
    99+
    2023-06-28
  • linux系统中如何使用echo命令
    小编给大家分享一下linux系统中如何使用echo命令,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!echo命令是linux中最基础的命令,也是很常用的命令,特别是在写shell脚本的时候,可能会经常被用到,虽然echo命...
    99+
    2023-06-28
  • Linux系统中如何使用ss命令
    这篇文章主要介绍了Linux系统中如何使用ss命令,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。ss是Socket Statistics的缩写。顾名思义,ss命令可以用来获取...
    99+
    2023-06-28
  • 如何使用Linux系统中dig命令
    这篇文章主要讲解了“如何使用Linux系统中dig命令”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何使用Linux系统中dig命令”吧!语法dig [@server] [-b addre...
    99+
    2023-06-12
  • Linux系统中rename命令如何使用
    Linux系统中rename命令如何使用,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Dos/Windows下,对文件改名用rename。而书上说,Linux下对文件或目录...
    99+
    2023-06-12
  • linux系统中semicolon命令如何使用
    linux系统中semicolon命令如何使用,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。当在同一行的2个命令使用semicolon也就是分号;分隔时,表示第一个comman...
    99+
    2023-06-12
  • linux系统中如何使用grep命令
    这篇文章将为大家详细讲解有关linux系统中如何使用grep命令,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。grep 指令用于查找内容包含指定的范本样式的文件,如果发现某文件的内容符合所指定的范本样式,...
    99+
    2023-06-28
  • linux系统中如何使用sesearch命令
    这篇文章给大家分享的是有关linux系统中如何使用sesearch命令的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。使用seinfo命令可以查询SELinux的策略提供多少相关规则,如果查到的相关类型或者布尔值,...
    99+
    2023-06-28
  • linux系统中如何使用chattr命令
    小编给大家分享一下linux系统中如何使用chattr命令,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!chattr命令的作用很大,其中一些功能是由Linux内核...
    99+
    2023-06-28
  • linux系统中如何使用sudo命令
    这篇文章主要为大家展示了“linux系统中如何使用sudo命令”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“linux系统中如何使用sudo命令”这篇文章吧。Linux 下使用Sudo 命令,可...
    99+
    2023-06-28
  • linux系统中如何使用tree命令
    这篇文章给大家分享的是有关linux系统中如何使用tree命令的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Linux tree命令用于以树状图列出目录的内容,执行tree指令,它会列出指定目录下的所有文件,包括...
    99+
    2023-06-28
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作