cURL-o命令赢得';t输出到文件,直到我停止java程序执行cURL命令

cURL-o命令赢得';t输出到文件,直到我停止java程序执行cURL命令,java,curl,Java,Curl,我正在编写一个Java程序,创建一个cURL命令并执行它。我没有遇到任何问题,除了一个命令不允许我将标准输出流到我的程序中。stdout具有执行未来cURL命令所需的信息 我一直在使用-o命令将stdout输出到一个.txt文件,但除非在执行cURL命令后立即停止Java程序,否则这是行不通的。 我也尝试过几种不同的流媒体技术,但似乎都不管用 不幸的是,我与之通信的API需要帐户信息才能执行许多命令,但我将共享不显示用户名和密码的代码 这是一个执行并返回未来命令所需值的命令: curl -o C

我正在编写一个Java程序,创建一个cURL命令并执行它。我没有遇到任何问题,除了一个命令不允许我将标准输出流到我的程序中。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文件的输出。最后的五位数是我需要的:

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方法:

publicstaticvoidcreatetype(stringtokenheader,stringdslencoded){
String curlCommand=“curl-oc:\\Users\\friza\\eclipse workspace\\canarycolamine\\birdseed.txt-k-J-X POST-v--include-H”+tokenHeader
+“-H\”内容类型:应用程序/x-www-form-urlencoded\“-d\”脚本=”
+DSL编码+
"\" https://api.gts.geant.net/taas/api/v2/projects/CanaryCoalMine/types";
试一试{
//执行Curl命令以创建新类型
Process Process=Runtime.getRuntime().exec(curlCommand);
System.out.println(“创建类型…”);
System.out.println(“发送:“+curl命令”);
}捕获(IOE异常){
//TODO自动生成的捕捉块
System.out.println(“IO异常:(”);
e、 printStackTrace();
}
}
博士 预期:一旦cURL命令执行,我希望在文件中看到给定的输出,而不停止执行该命令的Java程序


实际结果:在我点击Java程序上的“停止”按钮之前,无法在.txt文件中看到上述输出。在我能够从文件中提取最后五位数字之前,无法继续执行该程序。由于未知原因,无法直接流式传输。

要添加到user207421所说的内容中

这很可能是缓冲区读取问题

处理外部进程非常困难,如果外部程序的缓冲区填满,它将停止响应/工作,直到缓冲区被清除

因此,当从外部进程读取缓冲区时,这些读取进程必须发生在它们自己的线程中

下面是我的团队不久前处理外部流程的一些工作中的一个简单示例

主要方法是

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();
        }
    }
}
处理长时间运行的外部流程是一件痛苦的事情。下面是一些其他资源来解释这些问题。我自己必须多次阅读所有这些链接,才能弄清楚到底在说什么,以及为什么很难让一切“恰到好处”


如果这是一个问题,为什么不捕获curl的stdout,然后直接解析它呢?或者更好的方法是,使用java库进行远程调用。我尝试过直接捕获stdout,这对其中一个curl命令有效,但对这个命令无效。我认为curl缓冲区有些奇怪,所以我添加了-N,所以它没有缓冲区,which只对响应的前半部分起作用,但在我停止Java程序之前,其余部分不会显示。从Java运行任何进程时,需要关闭进程的标准输入并调用
Process.waitFor()