从java程序执行cat命令不能按预期工作

时间:2015-06-03 04:15:18

标签: java shell exec cat

我试图在java程序中使用cat命令将两个文件合并为一个。包含cat命令的代码行接受两个文件file1和file2,并写入名为combinedfile的第三个文件。但是,我观察到的是,我的程序只显示终端上的输出,而不是创建这个文件(combinedfile)并写入它。

如何确保将两个文件确实复制到第三个文件。

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

public class ExecuteShellCommand 
{

    public static void main(String[] args) 
    {

        ExecuteShellCommand obj = new ExecuteShellCommand();

        String command = "cat file1 file2 > combinedfile";

        String output = obj.executeCommand(command);

        System.out.println(output);

    }

    private String executeCommand(String command) 
    {

        StringBuffer output = new StringBuffer();

        Process p;
        try 
        {
            p = Runtime.getRuntime().exec(command);
            p.waitFor();
            BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));

            String line = "";           

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

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

        return output.toString();

    }

}

编辑:

我按照建议尝试使用ProcessBuilder,但是我收到了这个错误。 代码

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.*;
import java.util.*;

public class ExecuteShellCommand
{
    public static void main(String[] args) 
    {
        try
        {            
            ProcessBuilder builder = new ProcessBuilder("cat", "/home/PepperBoy/Desktop/file1.txt","/home/PepperBoy/Desktop/file2.txt");
            File combinedFile = new File("/home/PepperBoy/Desktop/file3.txt");
            builder.redirectOutput(combinedFile);
            builder.redirectError(combinedFile);
            Process p = builder.start();
        } 
        catch(IOException e)
        {
                e.printStackTrace();
        }

    }
}

错误

ExecuteShellCommand.java:14: cannot find symbol
symbol  : method redirectOutput(java.io.File)
location: class java.lang.ProcessBuilder
            builder.redirectOutput(combinedFile);

1 个答案:

答案 0 :(得分:0)

我找到了related question。要从那里找到的几个答案中总结有用的东西,文件重定向需要一个shell,但exec没有shell上下文。幸运的是,您可以使用ProcessBuilder执行重定向流程。对于您的情况,这看起来像:

public static void main(String[] args) 
{

    try{            
        ProcessBuilder builder = new ProcessBuilder("cat", "file1","file2");
        File combinedFile = new File("combinedFile");
        builder.redirectOutput(combinedFile);
        builder.redirectError(combinedFile);
        Process p = builder.start();
    } catch(IOException e){
        //handle exception...
    }

}

注意:调用redirectErrorredirectOutput时可能会收到错误,指出无法找到该符号。如果您在1.7之前编译Java版本,则会发生这种情况,因为1.7 is when these methods were introduced.如果可以升级Java,那么这样做将消除此错误。

如果可以升级Java,则以下代码将起作用:

public static void main(String[] args) 
{

    try{            
        ProcessBuilder builder = new ProcessBuilder("cat", "file1","file2");
        File combinedFile = new File("combinedFile");
        Process p = builder.start();

        InputStream isFromCat = p.getInputStream();
        OutputStream osCombinedFile = new FileOutputStream(combinedFile);

        byte[] buffer = new byte[1024];
        int read = 0;
        while((read = isFromCat.read(buffer)) != -1) {
            osCombinedFile.write(buffer, 0, read);
        }

    } catch(IOException e){
        //handle exception...
    }

}

值得注意的是,对cat进行系统调用并不是从Java组合文件的最佳方式。我一直认为这是一个玩具案例,代表一个更复杂的用例。如果你真正想做的就是组合两个文件,你应该编写代码以避免系统调用,只需通过读入输入流来附加文件,然后将它们写入结果文件。如果你在解决这个问题时遇到了麻烦,那些细节肯定属于另一个问题。