Команда cURL -o не будет выводиться в файл, пока я не остановлю Java-программу, выполняющую команду cURL - PullRequest
3 голосов
/ 20 июня 2019

Я пишу программу на Java, которая создает команду cURL и выполняет ее.У меня не было никаких проблем, за исключением того, что одна команда не позволит мне направить стандартный вывод в мою программу.Стандартный вывод имеет информацию, необходимую для выполнения будущих команд cURL.

Я использовал команду -o для вывода stdout в файл .txt, но это не сработает, если я не остановлю программу Java сразу после выполнения команды cURL.Я также пробовал несколько разных методов потоковой передачи, но ни одна из них не работает.

К сожалению, API, с которым я общаюсь, требует информацию об учетной записи для выполнения многих команд, но я поделюсь кодом, который не отображает мое имя пользователя и пароль.

Этоэто команда, которая выполняет и возвращает значение, которое мне нужно для будущих команд:

curl -o C:\Users\friza\eclipse-workspace\CanaryCoalMine\birdseed.txt -k -J -X POST -v --include -H "X-gts-token:xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx" https://api.gts.geant.net/taas/api/v2/projects/CanaryCoalMine/types/OneHost/reservations

Это вывод в файл birdseed.txt.Мне нужно пятизначное значение в самом конце:

HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Thu, 20 Jun 2019 16:25:07 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.google.com/recaptcha http://www.springframework.org http://java.sun.com/jsp https://www.google.com/jsapi https://www.google.com https://www.gstatic.com code.jquery.com ajax.googleapis.com https://*.bootstrapcdn.com https://*.cloudflare.com; img-src 'self' http://195.113.161.164:* https://www.gstatic.com/recaptcha code.jquery.com; style-src 'self' 'unsafe-inline' https://*.bootstrapcdn.com https://*.cloudflare.com https://fonts.googleapis.com code.jquery.com; font-src 'self' https://themes.googleusercontent.com https://*.bootstrapcdn.com https://*.cloudflare.com; frame-src 'self' 'unsafe-inline' https://www.google.com; object-src 'none'
Expect-CT: enforce; max-age=3600
Strict-Transport-Security: max-age=31622400; includeSubDomains; preload
Referrer-Policy: no-referrer
Feature-Policy: geolocation 'none';midi 'none';notifications 'none';push 'none';sync-xhr 'none';microphone 'none';camera 'none';magnetometer 'none';gyroscope 'none';speaker 'self';vibrate 'none';fullscreen 'self';payment 'none';

10940

Это метод Java, который я использую для выполнения приведенного выше кода:

public static void createType(String tokenHeader, String dslEncoded) {
        String curlCommand = "curl -o C:\\Users\\friza\\eclipse-workspace\\CanaryCoalMine\\birdseed.txt -k -J -X POST -v --include -H "+tokenHeader
                +" -H \"Content-Type: application/x-www-form-urlencoded\" -d \"script="
                +dslEncoded+
                "\" https://api.gts.geant.net/taas/api/v2/projects/CanaryCoalMine/types";



        try {
            //execute Curl Command to create new type
            Process process = Runtime.getRuntime().exec(curlCommand);

            System.out.println("Creating Type...");

            System.out.println("Sent: " + curlCommand);



        } catch (IOException e) {
            // TODO Auto-generated catch block
            System.out.println("IO EXCEPTION :( ");
            e.printStackTrace();

        }
    }

TL; Ожидаемый DR: После выполнения команды cURL я хочу увидеть заданный вывод в файле БЕЗ остановки программы Java, которая выполняет команду.

Фактические результаты: Невозможно увидеть вышеуказанный вывод в файле .txt, пока я не нажму STOPна программе Java.Невозможно продолжить работу с программой, пока я не смогу извлечь из файла последние пять цифр.Потоковая передача невозможна по неизвестной причине.

1 Ответ

0 голосов
/ 24 июня 2019

Чтобы добавить к тому, что пользователь207421 сказал ...

Скорее всего, это проблема чтения из буфера.

Работа с внешними процессами довольно сложна, и если буфер внешней программы заполняется, он перестанет отвечать / работать, пока этот буфер не будет очищен.

Поэтому при чтении буферов из внешнего процесса эти процессы чтения должны происходить в своих собственных потоках.

ВотПростой пример из некоторой работы, которую моя команда недавно выполнила для работы с внешними процессами.

Основной метод ...

package processbuilder;

import processbuilder.streamreader.PrintStreamStreamReader;

public class CurlProcessBuilder {

    public static void main(String... args) throws Exception {

        ProcessBuilder processBuilder = new ProcessBuilder("curl", "-v", "-s", "-k", "https://localhost:8443");

        Process process = processBuilder.start();

        PrintStreamStreamReader outReader = new PrintStreamStreamReader(System.out, process.getInputStream());
        Thread outThread = new Thread(outReader);
        outThread.start();

        PrintStreamStreamReader errReader = new PrintStreamStreamReader(System.err, process.getErrorStream());
        Thread errThread = new Thread(errReader);
        errThread.start();

        int exitValue = process.waitFor();
        System.out.println("Exit value: " + exitValue);
    }
}

Потоки, используемые для чтения из буфера процессов ...

package processbuilder.streamreader;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;

public class PrintStreamStreamReader implements Runnable {

    private PrintStream printStream;
    private InputStream inputStream;

    public PrintStreamStreamReader(PrintStream printStream, InputStream inputStream) {

        this.printStream = printStream;
        this.inputStream = inputStream;
    }

    @Override
    public void run() {

        try {

            int c;
            byte[] data = new byte[1024];
            while ((c = inputStream.read(data, 0, data.length)) != -1) {

                printStream.write(data, 0, c);
            }

        } catch (IOException e) {

            e.printStackTrace();
        }
    }
}

Работа с длительным внешним процессом - это боль.Вот некоторые другие ресурсы, объясняющие проблемы.Мне приходилось много раз читать все эти ссылки, чтобы понять, что на самом деле говорилось и почему так сложно все сделать «правильно».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...