Java inputstream печатает для консольного подключения к содержанию

Возможно, самый простой способ понять код - это работать в обратном порядке. Мы начнем со строки для печати - для баланса мы будем использовать «C ++ Rocks». Важный момент: точно так же, как и оригинал, он ровно восемь символов. Поскольку мы собираемся сделать (примерно) как оригинал и распечатать его в обратном порядке, мы начнем с того, что поместим его в обратном порядке. Для нашего первого шага мы просто рассмотрим эту битовую комбинацию как double и распечатаем результат:

#include <stdio.h>

char string[] = "skcoR++C";

int main(){
    printf("%f\n", *(double*)string);
}

Это приводит к 3823728713643449.5. Итак, мы хотим манипулировать этим каким-то образом, что не очевидно, но легко изменить. Я буду полу-произвольно выбирать умножение на 256, что дает нам 978874550692723072. Теперь нам просто нужно написать некоторый запутанный код для деления на 256, а затем распечатать отдельные байты этого в обратном порядке:

#include <stdio.h>

double x [] = { 978874550692723072, 8 };
char *y = (char *)x;

int main(int argc, char **argv){
    if (x[1]) {
        x[0] /= 2;  
        main(--x[1], (char **)++y);
    }
    putchar(*--y);
}

Теперь у нас есть много приведений, передающих аргументы (рекурсивному) main, которые полностью игнорируются (но оценка, чтобы получить приращение и уменьшение крайне важны), и, конечно, это совершенно произвольно выглядящее число, чтобы скрыть тот факт, что то, что мы делаем, действительно довольно просто.

Конечно, так как все дело в запутывании, если мы чувствуем, что мы можем сделать больше шагов. Например, мы можем воспользоваться оценкой короткого замыкания, чтобы превратить наш оператор if в одно выражение, поэтому тело main выглядит следующим образом:

x[1] && (x[0] /= 2,  main(--x[1], (char **)++y));
putchar(*--y);

Для всех, кто не Привычный к запутанному коду (и / или коду для гольфа) это начинает выглядеть довольно странно - вычисление и отбрасывание логического and некоторого бессмысленного числа с плавающей запятой и возвращаемого значения из main, которое даже не возвращает значение. Хуже того, не осознавая (и не задумываясь) о том, как работает оценка короткого замыкания, может быть даже не сразу очевидно, как избежать бесконечной рекурсии.

Наш следующий шаг, вероятно, будет отделять печать каждого символа от поиска этого символа. Мы можем сделать это довольно легко, сгенерировав правильный символ в качестве возвращаемого значения из main, и распечатав то, что возвращает main:

x[1] && (x[0] /= 2,  putchar(main(--x[1], (char **)++y)));
return *--y;

По крайней мере для меня, это кажется достаточно запутанным, поэтому я оставлю это при этом.

14
задан Jon Skeet 5 July 2009 в 08:34
поделиться

2 ответа

Если вы хотите распечатать содержимое веб-страницы, вам необходимо работать с 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();
    }  
19
ответ дан 1 December 2019 в 12:39
поделиться

Если вы хотите получить содержимое веб-страницы , вам следует взглянуть на apache httpclient вместо того, чтобы кодировать его самостоятельно, в целях обучения или по любой другой действительно веской причине.

1
ответ дан 1 December 2019 в 12:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: