2010-08-04 3 views
25

Я хочу создать diff двух файлов. Я пробовал искать код в Java, который делает это, но не нашел для него простого кода/кода. Следовательно, я подумал, могу ли я каким-то образом запустить команду linux diff/sdiff из моего java-кода и заставить его вернуть файл, в котором хранится diff, но это было бы здорово.Как запустить команды linux в java-коде?

Предположим, что есть два файла fileA и fileB. Я должен иметь возможность хранить их diff в файле с именем fileDiff через мой java-код. Тогда выборка данных из fileDiff не была бы большой проблемой.

+0

Обязательно прочитайте: http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps. html –

ответ

10

Вам не нужно хранить различий в 3-файл, а затем читать в Вместо этого вы сделать использование Runtime.exec

Process p = Runtime.getRuntime().exec("diff fileA fileB");                                      
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream())); 
while ((s = stdInput.readLine()) != null) { 
     System.out.println(s); 
} 
33

Вы можете использовать java.lang.Runtime.exec для запуска простого кода. Это дает вам обратно Process, и вы можете прочитать его стандартный вывод напрямую, не временно сохраняя вывод на диске.

Например, вот полная программа, которая продемонстрирует, как это сделать:

import java.io.BufferedReader; 
import java.io.InputStreamReader; 

public class testprog { 
    public static void main(String args[]) { 
     String s; 
     Process p; 
     try { 
      p = Runtime.getRuntime().exec("ls -aF"); 
      BufferedReader br = new BufferedReader(
       new InputStreamReader(p.getInputStream())); 
      while ((s = br.readLine()) != null) 
       System.out.println("line: " + s); 
      p.waitFor(); 
      System.out.println ("exit: " + p.exitValue()); 
      p.destroy(); 
     } catch (Exception e) {} 
    } 
} 

После компиляции и запуска, он выводит:

line: ./ 
line: ../ 
line: .classpath* 
line: .project* 
line: bin/ 
line: src/ 
exit: 0 

, как и ожидалось.

Вы также можете получить error stream для стандартной ошибки процесса и output stream для стандартного ввода процесса, достаточно смутно. В этом контексте вход и выход обращаются вспять, так как он вводит от процесс к этому (то есть стандартный вывод процесса).

Если вы хотите объединить стандартный вывод и ошибку процесса с Java (в отличие от использования 2>&1 в действительной команде), вы должны посмотреть на ProcessBuilder.

+0

Спасибо всем за ваши ответы. – chitresh

4
Runtime run = Runtime.getRuntime(); 
//The best possible I found is to construct a command which you want to execute 
//as a string and use that in exec. If the batch file takes command line arguments 
//the command can be constructed a array of strings and pass the array as input to 
//the exec method. The command can also be passed externally as input to the method. 

Process p = null; 
String cmd = "ls"; 
try { 
    p = run.exec(cmd); 

    p.getErrorStream(); 
    p.waitFor(); 

} 
catch (IOException e) { 
    e.printStackTrace(); 
    System.out.println("ERROR.RUNNING.CMD"); 

}finally{ 
    p.destroy(); 
} 
12

Вы также можете написать файл сценария оболочки и вызвать этот файл из java-кода. как показано ниже

{ 
    Process proc = Runtime.getRuntime().exec("./your_script.sh");       
    proc.waitFor(); 
} 

Написать команды Linux в файле сценария, когда выполнение закончится вы можете прочитать файл различий в Java.

Преимущество такого подхода заключается в том, что вы можете изменять команды без изменения кода Java.

4

попытаться использовать unix4j. это о библиотеке в java для запуска команды linux. например, если у вас есть команда вроде: cat test.txt | grep «Вторник» | sed "s/kilogram/kg/g" | sort в этой программе станет: Unix4j.cat ("test.txt"). grep ("Tuesday"). sed ("s/kilogram/kg/g").Сортировать(); Команды

1

если отверстие в окнах

try { 
     //chm file address 
     String chmFile = System.getProperty("user.dir") + "/chm/sample.chm"; 
     Desktop.getDesktop().open(new File(chmFile)); 
    } catch (IOException ex) { 
     Logger.getLogger(Frame.class.getName()).log(Level.SEVERE, null, ex); 
     { 
      JOptionPane.showMessageDialog(null, "Terjadi Kesalahan", "Error", JOptionPane.WARNING_MESSAGE); 
     } 
    } 
0

Вы можете назвать время выполнения из Java как для Windows, и Linux.

import java.io.*; 

public class Test{ 
    public static void main(String[] args) 
    { 
      try 
      { 
      Process process = Runtime.getRuntime().exec("pwd"); // for Linux 
      //Process process = Runtime.getRuntime().exec("cmd /c dir"); //for Windows 

      process.waitFor(); 
      BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); 
      String line; 
       while ((line=reader.readLine())!=null) 
       { 
       System.out.println(line); 
       } 
      }  
       catch(Exception e) 
      { 
       System.out.println(e); 
      } 
      finally 
      { 
       process.destroy(); 
      } 
    } 
} 

Надеется, что это помогает .. :)

0

Предложенных решения могут быть оптимизированы с использованием commons.io, обработки потока ошибок, и использование исключений. Я хотел бы предложить, чтобы обернуть как это для использования в Java 8 или более поздней версии:

public static List<String> execute(final String command) throws ExecutionFailedException, InterruptedException, IOException { 
    try { 
     return execute(command, 0, null, false); 
    } catch (ExecutionTimeoutException e) { return null; } /* Impossible case! */ 
} 

public static List<String> execute(final String command, final long timeout, final TimeUnit timeUnit) throws ExecutionFailedException, ExecutionTimeoutException, InterruptedException, IOException { 
    return execute(command, 0, null, true); 
} 

public static List<String> execute(final String command, final long timeout, final TimeUnit timeUnit, boolean destroyOnTimeout) throws ExecutionFailedException, ExecutionTimeoutException, InterruptedException, IOException { 
    Process process = new ProcessBuilder().command("bash", "-c", command).start(); 
    if(timeUnit != null) { 
     if(process.waitFor(timeout, timeUnit)) { 
      if(process.exitValue() == 0) { 
       return IOUtils.readLines(process.getInputStream(), StandardCharsets.UTF_8); 
      } else { 
       throw new ExecutionFailedException("Execution failed: " + command, process.exitValue(), IOUtils.readLines(process.getInputStream(), StandardCharsets.UTF_8)); 
      } 
     } else { 
      if(destroyOnTimeout) process.destroy(); 
      throw new ExecutionTimeoutException("Execution timed out: " + command); 
     } 
    } else { 
     if(process.waitFor() == 0) { 
      return IOUtils.readLines(process.getInputStream(), StandardCharsets.UTF_8); 
     } else { 
      throw new ExecutionFailedException("Execution failed: " + command, process.exitValue(), IOUtils.readLines(process.getInputStream(), StandardCharsets.UTF_8)); 
     } 
    } 
} 

public static class ExecutionFailedException extends Exception { 

    private static final long serialVersionUID = 1951044996696304510L; 

    private final int exitCode; 
    private final List<String> errorOutput; 

    public ExecutionFailedException(final String message, final int exitCode, final List<String> errorOutput) { 
     super(message); 
     this.exitCode = exitCode; 
     this.errorOutput = errorOutput; 
    } 

    public int getExitCode() { 
     return this.exitCode; 
    } 

    public List<String> getErrorOutput() { 
     return this.errorOutput; 
    } 

} 

public static class ExecutionTimeoutException extends Exception { 

    private static final long serialVersionUID = 4428595769718054862L; 

    public ExecutionTimeoutException(final String message) { 
     super(message); 
    } 

} 
Смежные вопросы