>

cURL 명령을 작성하고 실행하는 Java 프로그램을 작성 중입니다. 하나의 명령으로 stdout을 내 프로그램으로 스트리밍 할 수 없다는 점을 제외하고는 아무런 문제가 없었습니다. stdout에는 향후 cURL 명령을 실행하는 데 필요한 정보가 있습니다.

-o 명령을 사용하여 stdout을 .txt 파일로 출력했지만 cURL 명령을 실행 한 직후 Java 프로그램을 중지하지 않으면 작동하지 않습니다. 또한 여러 가지 스트리밍 기술을 시도했지만 아무것도 작동하지 않는 것 같습니다.

안타깝게도, 내가 통신하는 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 파일에 대한 출력입니다. 맨 끝에 5 자리 값이 필요합니다.

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 프로그램을 중지하지 않고 파일에서 주어진 출력을보고 싶습니다.

실제 결과 : Java 프로그램에서 STOP을 누르기 전까지 .txt 파일에서 위 출력을 볼 수 없습니다. 파일에서 마지막 5 자리 숫자를 추출 할 수있을 때까지 프로그램을 진행할 수 없습니다. 알 수없는 이유로 직접 스트리밍 할 수 없습니다.


  • 답변 # 1

    사용자 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();
            }
        }
    }
    
    

    오랫동안 실행되는 외부 프로세스를 다루는 것은 고통 스럽다. 다음은 문제를 설명하는 다른 리소스입니다. 나는이 모든 링크를 여러 번 읽어야 실제로 실제로 무엇을 말했는지, 왜 모든 것이 '정확한지'이해하기 어려운 이유를 알 수있었습니다.

    FIO07-J. 외부 프로세스가 IO 버퍼를 차단하지 않도록 함

    Runtime.exec ()가 작동하지 않는 경우

    Java exec-Java ProcessBuilder 및 프로세스 (1 부)로 시스템 프로세스 실행

    Java exec-Java ProcessBuilder 및 프로세스 (2 부)로 시스템 프로세스 실행

    Java ExecutorService에 대한 안내서

관련 자료

  • 이전 python - 사전 (람다가 아님)을 사용하여 사전 목록에서 dict 값 업데이트
  • 다음 dart - flutter 앱에서 기본 경로를 재설정하는 방법 - 그것은 경로를 팝하고 네비게이터를 사용하여 새로운 경로로 대체