使用Java运行“tar”命令,但生成tar文件需要花费很多时间

时间:2013-12-12 13:37:20

标签: java tar runtime.exec

在我的项目中,我需要为用户生成代理,代理包括一些jar(大约22M),一些源类(大约200k)和XML。服务器将为不同用户生成不同的xml,因此我必须动态生成代理。我使用Runtime.getRuntime().exec("tar...")来tar文件来生成代理。

当我进行单元测试时,发电需要花费很多时间,每个代理商大约需要2分钟。我不能让用户等待一个页面2分钟...所以它是否有任何其他方式使这个程序更有效率,或者有另一种方法快速,顺利地生成代理?欣赏!

 /**
  * tar the agents
  * @param inputFiles agent files
  * @param outputFile agent tar
  * @param baseDir the directory path to run "tar" command
  */
 public static void tarFile(String[] inputFiles,String outputFile,String baseDir){
     String cmd="tar -zcf "+outputFile+" ";
     for (int i = 0; i < inputFiles.length; i++) {
        cmd+=inputFiles[i]+" ";
    }
     System.out.println(cmd);
     try {
        Process process=Runtime.getRuntime().exec(cmd, null, new File(baseDir));
        BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(process.getInputStream()));
        String s;
        while ((s=bufferedReader.readLine())!=null) {
            System.out.println(s);
        }
        process.waitFor();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
 }

这是我的tar类,基于param的是设置命令的执行路径

2 个答案:

答案 0 :(得分:1)

使用Apache Commons Compress直接在Java中创建tar存档 请参阅TarArchiveOutputStream

这是一个完整的servlet,可以动态创建tar输出:

import java.io.*;   
import javax.servlet.http.*;    
import org.apache.commons.compress.archivers.tar.*;
import org.apache.commons.compress.utils.IOUtils;

public class Web extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String[] files = { 
                "/path/to/file1",
                "/path/to/file2",
        };

        resp.setContentType("application/x-tar");
        try (TarArchiveOutputStream out = new TarArchiveOutputStream(resp.getOutputStream())) {
            for (String name: files) {
                File file = new File(name);
                TarArchiveEntry entry = new TarArchiveEntry(file);
                out.putArchiveEntry(entry);
                try (InputStream in = new FileInputStream(file)) {
                    IOUtils.copy(in, out);
                }
                out.closeArchiveEntry();
            }
        }
    }
}

客户端将立即开始接收存档,而无需等待提前创建tar文件。此外,这不需要将存档写入光盘。

答案 1 :(得分:1)

我需要查看传递给Runtime.getRuntime()。exec的实际tar命令。

有4个因素真正影响将文件压缩到tarball的速度:

  1. 包装盒上的CPU速度
  2. 包装盒上的I / O速度
  3. 要归档的源数据量
  4. 压缩
  5. rzymek指出您可以使用Apache Commons Compress本地生成文件。但是,除非我们理解命令行方法的约束,否则我不确定会更快。

    如果您只是使用外壳自行开启,速度是否可比?如果是这样,请尝试降低压缩率,甚至完全关闭它(删除tar czf中的“z”选项。)

    如果要压缩tar文件并且需要压缩,那么如果XML很小,你可以预压缩JAR文件(我想如果我记得它们已经被压缩了,但是你可能需要检查一下因为压缩压缩文件没有任何结果(有时速度较慢!)

    压缩比率)然后使tarball解压缩