在Java Socket编程中分离Get请求响应主体

时间:2017-09-30 21:01:22

标签: java sockets get httpresponse bufferedreader

我试图使用java编写一个类似curl的程序,它只使用java套接字编程(而不是apache http客户端或任何其他API) 我希望可以选择向用户显示整个响应或仅响应我的get请求的响应。目前想出了以下代码:

BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
        String t;
        while ((t = br.readLine()) != null) {
            if (t.isEmpty() && !parameters.isVerbose()) {
                StringBuilder responseData = new StringBuilder();
                while ((t = br.readLine()) != null) {
                    responseData.append(t).append("\r\n");
                }
                System.out.println(responseData.toString());
                parameters.verbose = false;
                break;
            } else if(parameters.isVerbose())// handle output
                System.out.println(t);
        }
        br.close();

当详细选项打开时,它可以快速运行并在不到一秒的时间内显示整个响应正文。但是当我想要拥有信息的正文时,需要花费太多时间(大约10秒)才能将其传出去。 有谁知道如何以更快的方式处理它? 谢谢。

1 个答案:

答案 0 :(得分:0)

我会假设你的意思是缓慢的是它几乎立即开始显示某些东西但是长时间保持在印刷线上。写入控制台需要花费时间,并且您在另一个代码路径中打印每行,然后首先将整个响应存储在内存中,然后将其刷新到控制台。

如果详细响应足够小以适应内存,您应该这样做,否则您可以决定批量打印任意数量的行(即;您在内存中累积n行然后刷新到控制台,清除StringBuilder并重复)。

实现我的建议最优雅的方法是使用PrintStream包裹BufferedOutputStream,自己包裹System.out。我的所有评论和建议都包含在以下代码段中:

private static final int BUFFER_SIZE = 4096;

public static void printResponse(Socket socket, Parameters parameters) throws IOException {
    try (BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
         PrintStream printStream = new PrintStream(new BufferedOutputStream(System.out, BUFFER_SIZE))) {

        // there is no functional difference in your code between the verbose and non-verbose code paths
        // (they have the same output). That's a bug, but I'm not fixing it in my snippet as I don't know
        // what you intended to do.
        br.lines().forEach(line -> printStream.append(line).append("\r\n"));
    }
}

如果它使用您不了解的任何语言结构,请随时提出进一步的问题。