49

我想创建两个文件的差异。我尝试在 Java 中搜索执行此操作的代码,但没有找到任何简单的代码/实用程序代码。因此,我想如果我能以某种方式从我的 java 代码中运行 linux diff/sdiff 命令并让它返回一个存储差异的文件,那就太好了。

假设有两个文件fileA和fileB。我应该能够通过我的 java 代码将它们的差异存储在一个名为 fileDiff 的文件中。然后从 fileDiff 获取数据将没什么大不了的。

4

9 回答 9

61

您可以使用java.lang.Runtime.exec来运行简单的代码。这会返回 aProcess并且您可以直接读取其标准输出,而无需将输出临时存储在磁盘上。

例如,这是一个完整的程序,将展示如何做到这一点:

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

正如预期的那样。

您还可以获得流程标准错误的错误流,以及流程标准输入的输出流,这很令人困惑。在这种情况下,输入和输出是相反的,因为它是进程到这个进程的输入(即进程的标准输出)。

如果您想合并来自 Java 的流程标准输出和错误(而不是2>&1在实际命令中使用),您应该查看ProcessBuilder.

于 2010-08-04T06:56:50.203 回答
22

您还可以编写一个 shell 脚本文件并从 java 代码调用该文件。如下所示

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

在脚本文件中写入 linux 命令,一旦执行结束,您可以读取 Java 中的 diff 文件。

这种方法的优点是您可以在不更改 java 代码的情况下更改命令。

于 2010-08-04T07:42:49.670 回答
14

您无需将差异存储在第三个文件中,然后从其中读取。相反,您可以使用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);
}
于 2010-08-04T06:56:33.587 回答
7

try to use unix4j. it s about a library in java to run linux command. for instance if you got a command like: cat test.txt | grep "Tuesday" | sed "s/kilogram/kg/g" | sort in this program will become: Unix4j.cat("test.txt").grep("Tuesday").sed("s/kilogram/kg/g").sort();

于 2013-07-28T23:16:47.913 回答
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();
}  
于 2010-08-04T06:57:38.437 回答
3

您可以从 java 为WindowsLinux调用运行时命令。

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();
             }  
    }
}

希望能帮助到你.. :)

于 2017-03-21T15:15:19.277 回答
2

建议的解决方案可以使用 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);
    }

}
于 2018-02-13T16:15:14.683 回答
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);
        }
    }
于 2014-01-06T03:49:36.253 回答
-2
ProcessBuilder processBuilder = new ProcessBuilder();

// -- Linux --

// Run a shell command
processBuilder.command("bash", "-c", "ls /home/kk/");

// Run a shell script
//processBuilder.command("path/to/hello.sh");

// -- Windows --

// Run a command
//processBuilder.command("cmd.exe", "/c", "dir C:\\Users\\kk");

// Run a bat file
//processBuilder.command("C:\\Users\\kk\\hello.bat");

try {

    Process process = processBuilder.start();

    StringBuilder output = new StringBuilder();

    BufferedReader reader = new BufferedReader(
            new InputStreamReader(process.getInputStream()));

    String line;
    while ((line = reader.readLine()) != null) {
        output.append(line + "\n");
    }

    int exitVal = process.waitFor();
    if (exitVal == 0) {
        System.out.println("Success!");
        System.out.println(output);
        System.exit(0);
    } else {
        //abnormal...
    }

} catch (IOException e) {
    e.printStackTrace();
} catch (InterruptedException e) {
    e.printStackTrace();
}
于 2018-04-20T13:37:58.963 回答