问题详细信息
我正在尝试从 java 调用 wget 来下载文件,但是我一直遇到一个奇怪的问题,即文件大小受到限制。
例如,发出“wgethttps://speed.hetzner.de/1GB.bin“,我正确地拥有 1GB.bin,文件大小为 1,048,576,000(正好是 1 GB)。但是当从 java 调用相同的命令时,我始终得到大约 40 MB 的文件。
调试
假设你已经安装了 JDK,下面是一个血管内皮生长因子重现此行为:
echo 'class RunCommand {
public static void main(String[] args) throws Exception {
String s = "";
for (int i=0; i < args.length; i++)
s += (i > 0 ? " " : "") + args[i];
System.out.println(Runtime.getRuntime().exec(s).waitFor());
}
}' > RunCommand.java
javac RunCommand.java
java RunCommand wget https://speed.hetzner.de/1GB.bin
我已经在干净的 AWS CentOS 7.6 机器上尝试过此操作:
- OpenJDK 7
- OpenJDK 8
- Oracle JDK 8
我总是得到相同的结果:java 挂起并且文件大小约为 40 MB。
我也尝试过增加堆大小,但-Xms1024m -Xmx1024m
没有效果,最后得出结论,堆大小不是问题。
现在,用 curl 再次运行完全相同的操作:
java RunCommand curl https://speed.hetzner.de/1GB.bin -o 1GB.bin
令人惊讶的是,这个方法有效,我成功得到了一个 1GB 的文件!
问题
所以这里有很多问题:
- 为什么 Java 在 40 MB 之后会挂起?
- 为什么总是正好 40 MB?(grepping 40
-XX:+PrintFlagsFinal
没有任何线索) - wget 和 curl 命令之间有什么区别,导致一个失败而另一个成功?
答案1
尝试在命令中添加 --quiet ;可能是标准输出已满,因为您没有通过输入流读取它。
这是从 wget 手册中提取的。
-q
--quiet
Turn off Wget’s output.
检查下面的代码片段。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Created on 2/13/2019.
*
* @author Julien Saab
*/
public class TestCommand {
public static void main(String[] args) throws Exception {
final List<String> commands = new ArrayList<>(Arrays.asList(args));
commands.add("--quiet");
final Process process = new ProcessBuilder().command(commands).start();
final int i = process.waitFor();
System.out.printf("Process exited with code %1$s\n", i);
}
}
我尝试过您使用的相同文件,它的大小已超过 41 MB(但我当然没有完全下载它)。
java TestCommand wget https://speed.hetzner.de/1GB.bin