Разделение тела ответа запроса на получение в Java Socket программировании

Я пытаюсь написать программу, похожую на завиток, с использованием java, которая использует только программирование сокетов java (а не http-клиент apache или любые другие API). Я хочу иметь возможность отображать весь или только текст ответа на мой запрос на получение пользователю. На данный момент придумал следующий код:

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 секунд). Кто-нибудь знает, как его можно обработать быстрее? Спасибо.


person Fezo    schedule 30.09.2017    source источник
comment
Просто комментарий: структура кода довольно странная, потому что вы используете весь поток во внутреннем цикле, поэтому внешний цикл бесполезен в невыясненном случае. Вы также можете исправить свои имена переменных (s и t не являются явными именами).   -  person Dici    schedule 01.10.2017
comment
Может быть, переключатель подробностей активен в другом месте вашего кода? Кажется, что вы отправляете заголовок типа Connection: close в одном случае, но не в другом.   -  person blafasel    schedule 01.10.2017
comment
@blafasel Я пробовал с теми же данными и только с логической разницей. когда я все это печатаю, все работает отлично и быстро. Но при обработке, имея только данные, она становится довольно медленной!   -  person Fezo    schedule 02.10.2017


Ответы (1)


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

Если подробный ответ достаточно мал, чтобы уместиться в памяти, вы должны сделать то же самое, в противном случае вы можете выбрать произвольное количество строк для печати партиями (т. Е. Вы накапливаете 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"));
    }
}

Если он использует какую-либо языковую конструкцию, о которой вы не знаете, не стесняйтесь задавать дополнительные вопросы.

person Dici    schedule 30.09.2017
comment
Спасибо за ваш ответ. На самом деле ничего не начинает отображаться в течение нескольких секунд, а затем все сходится! И результаты подробного и не подробного вывода различаются. один показывает весь ответ, а другой - только данные, полученные в ответе. - person Fezo; 02.10.2017
comment
Таким образом, можно получить тело, отделив его от остальной части ответа пустой строкой. эта часть предназначена для извлечения тела. - person Fezo; 02.10.2017
comment
@Fezo Я не вижу разницы в вашем коде. Вы показываете все строки в обоих случаях (кроме первой в неполнотном случае, но только если она пуста, так что особой разницы нет). - person Dici; 02.10.2017
comment
Вы попробовали мое предложение? - person Dici; 02.10.2017