1

Детали вопроса

Я пытаюсь вызвать wget из java для загрузки файла, но продолжаю сталкиваться со странной проблемой, когда размер файла будет ограничен.

Например, при выдаче «wget https://speed.hetzner.de/1GB.bin » у меня правильно 1GB.bin с размером файла 1 048 576 000 (ровно 1 ГБ). Но при вызове одной и той же команды из Java, я постоянно получаю примерно 40 МБ файла.

отладка

Предполагая, что у вас установлен JDK, вот MCVE, который воспроизводит это поведение:

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 МБ.

Я также попытался увеличить размер кучи с -Xms1024m -Xmx1024m но безрезультатно, что размер кучи не является проблемой.

Теперь снова запустите ту же самую вещь с помощью curl:

java RunCommand curl https://speed.hetzner.de/1GB.bin -o 1GB.bin

Это удивительно работает, и я успешно получаю файл 1 ГБ!

Вопросы

Так что здесь много вопросов:

  1. Почему Java висит после 40 МБ?
  2. Почему всегда ровно 40 МБ? (grepping 40 in -XX:+PrintFlagsFinal дает подсказки)
  3. Какая разница между командами wget и curl, которая может привести к тому, что одна из них выйдет из строя, а другая преуспеет?

1 ответ1

0

Попробуйте добавить --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 МБ (но, конечно, я его не полностью загрузил).

java TestCommand wget https://speed.hetzner.de/1GB.bin

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .