Мы работаем, чтобы уменьшить задержку и увеличить выполнение процесса, записанного в Java, который использует данные (xml строки) от сокета через readLine () метод класса BufferedReader. Данные разграничены к концу разделителя строки (\n), и каждая строка может иметь переменную длину (6 кбит - 32 кбита). Наш код похож:
Socket sock = connection;
InputStream in = sock.getInputStream();
BufferedReader inputReader = new BufferedReader(new InputStreamReader(in));
...
do
{
String input = inputReader.readLine();
// Executor call to parse the input thread in a seperate thread
}while(true)
Таким образом, у меня есть несколько вопросов:
Я справляюсь (медленно) с библиотеками IO Java, таким образом, любые указатели очень ценятся.
Спасибо!
Вернется ли метод inputReader.readLine(), как только получит символ \n или будет ждать, пока буфер не заполнится?
Есть ли более быстрый способ получения данных из сокета, чем использование BufferedReader?
BufferedReader подразумевает некоторое копирование данных. Можно попробовать NIO apis, который позволяет избежать копирования, но прежде чем тратить на это время, лучше провести анализ, чтобы понять, действительно ли узким местом является ввод-вывод. Более простым быстрым решением является добавление BufferedInputStream
вокруг сокета, чтобы каждое чтение не ударяло по сокету (неясно, делает ли InputStreamReader какую-либо буферизацию самостоятельно), например.
new BufferedReader(new InputStreamReader(new BufferedInputStream(in)))
Что произойдет, если размер входной строки меньше размера буфера приема сокета?
Что происходит, когда размер входной строки больше размера буфера приема сокета?
Подводя итог, можно сказать, что BufferedReader блокирует только в случае крайней необходимости.
Одним из преимуществ BufferedReader является то, что он обеспечивает уровень разделения (буфер) между методами ввода (read, readLine и т. Д.), Которые вы use и фактическое чтение сокета, поэтому вам не нужно беспокоиться обо всех случаях вроде «большая часть строки находится в буфере, но вам нужно прочитать другой буфер, чтобы получить \ n» и т. д.
У вас сделали измерение производительности, которое указывает на то, что использование BufferedReader является проблемой для вашего приложения? Если нет, я бы посоветовал вам начать с выбора метода ввода, который обеспечивает желаемую функциональность (линейный ввод, завершаемый \ n, по его звуку), и беспокоиться о том, есть ли «более быстрый» способ сделать это. только если вы обнаружите, что метод ввода является узким местом.
Если линейный ввод действительно то, что вам нужно, вы в конечном итоге будете использовать какой-то буфер, такой как BufferedReader, так зачем заново изобретать это колесо?
Ответ на ваш первый вопрос - да и нет. Если буфер уже содержит терминатор строки, он вернется немедленно, однако, если он не содержит терминатора, он попытается заполнить буфер, но не обязательно полностью. Он будет считываться только до тех пор, пока не будут достигнуты какие-либо новые данные (по крайней мере, один символ) или EOF.
Одна из приятных вещей в Java заключается в том, что библиотеки имеют открытый исходный код,поэтому, если у вас есть полная копия JDK, вы можете посмотреть на источник самостоятельно, чтобы ответить на эти типы вопросов. Я использую eclipse в качестве своей IDE, и по умолчанию, если вы наведите курсор на имя класса и нажмете F3, это приведет вас к источнику (именно так я получил ответ выше). Предостережение заключается в том, что при стандартном дистрибутиве исходный код для некоторых внутренних классов / машинного кода недоступен.
Что касается вашего второго вопроса, я бы сказал в целом нет, так как логика, используемая BufferedReader, в целом та же самая, которую любой код должен был бы воссоздать для достижения той же задачи. Единственное, что может замедлить BufferedReader, это то, что внутренне он использует StringBuffer, который синхронизируется, вместо несинхронизированного StringBuilder.