Java InputStream将内容打印到控制台

16
sock = new Socket("www.google.com", 80);
       out  = new BufferedOutputStream(sock.getOutputStream());
       in   = new BufferedInputStream(sock.getInputStream());

当我尝试打印“in”中的内容时,如下所示:
 BufferedInputStream bin = new BufferedInputStream(in);
 int b;
 while ( ( b = bin.read() ) != -1 )
 {

     char c = (char)b;         

     System.err.print(""+(char)b); //This prints out content that is unreadable.
                                   //Isn't it supposed to print out html tag?
 }

请提供一个简短但完整的示例。您还没有展示如何向Google发送请求。例如,如果您指定可以处理gzipped数据,则需要先解压缩输出。 - Jon Skeet
请注意,您当前的代码实际上是假定 ISO-Latin-1 编码的。 - Jon Skeet
嗨,在我打开新的Socket()之后,我执行了一个“get index.html”并将其发送到“out”,然后尝试获取“in”,就像上面的代码一样。我没有指定处理gzipped,如何找出它是否被gzipped? - cometta
如果内容被gzip压缩,将在头部中声明(这不会发生)。HTTP 0.9语法往往不再起作用。您需要类似于“GET /index.html HTTP1.0\r\n\r\n”或更好的“GET /index.html HTTP1.1\r\nHost: www.google.com\r\n\r\n”(如我所记得的那样)。 - Tom Hawtin - tackline
3个回答

20
如果你想打印网页内容,你需要使用HTTP协议。你不必自己实现它,最好的方法是使用现有的实现,比如Java API HttpURLConnection或Apache的HttpClient
下面是使用HttpURLConnection的示例:
URL url = new URL("http","www.google.com");
HttpURLConnection urlc = (HttpURLConnection)url.openConnection();
urlc.setAllowUserInteraction( false );
urlc.setDoInput( true );
urlc.setDoOutput( false );
urlc.setUseCaches( true );
urlc.setRequestMethod("GET");
urlc.connect();
// check you have received an status code 200 to indicate OK
// get the encoding from the Content-Type header
BufferedReader in = new BufferedReader(new InputStreamReader(urlc.getInputStream()));
String line = null;
while((line = in.readLine()) != null) {
  System.out.println(line);
}

// close sockets, handle errors, etc.

如上所述,您可以通过添加Accept-Encoding头并检查响应的Content-Encoding头来节省流量。

以下是来自这里的HttpClient示例:

   // Create an instance of HttpClient.
    HttpClient client = new HttpClient();

    // Create a method instance.
    GetMethod method = new GetMethod(url);

    // Provide custom retry handler is necessary
    method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, 
            new DefaultHttpMethodRetryHandler(3, false));

    try {
      // Execute the method.
      int statusCode = client.executeMethod(method);

      if (statusCode != HttpStatus.SC_OK) {
        System.err.println("Method failed: " + method.getStatusLine());
      }

      // Read the response body.
      byte[] responseBody = method.getResponseBody();

      // Deal with the response.
      // Use caution: ensure correct character encoding and is not binary data
      System.out.println(new String(responseBody));

    } catch (HttpException e) {
      System.err.println("Fatal protocol violation: " + e.getMessage());
      e.printStackTrace();
    } catch (IOException e) {
      System.err.println("Fatal transport error: " + e.getMessage());
      e.printStackTrace();
    } finally {
      // Release the connection.
      method.releaseConnection();
    }  

特别是对于 HttpClient,给个赞。只要你想要做任何超越简单 GET 的事情,它就非常有用了。 - Brian Agnew
2
HttpURLConnection 不支持处理 gzip 压缩的内容。我是吃了亏才知道的。 - Jeremy Salwen

16

使用 Java 8 Stream API 很容易从 Stream 中创建一个字符串:

new BufferedReader(new InputStreamReader(in)).lines().collect(Collectors.joining("\n"))

使用IntelliJ,我甚至可以将此设置为调试表达式: enter image description here

我猜在Eclipse中也会类似地工作。


1
如果你想获取网页的内容,你应该看一下apache httpclient,而不是自己编写代码,除非出于学习目的或其他非常好的原因。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接