Что такое буферизация в java
Перейти к содержимому

Что такое буферизация в java

  • автор:

Что такое буферизация в java

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

Традиционное понятие двойной буферизации в приложениях Java является довольно прямым: создайте внеэкранное изображение, потяните к тому изображению, используя графический объект изображения, тогда, за один шаг, вызовите drawImage, используя графический объект целевого окна и внеэкранное изображение. Вы, возможно, уже заметили, что Swing использует этот метод во многих из его компонентов, обычно включаемых по умолчанию, используя метод setDoubleBuffered.

Экранная поверхность обычно упоминается как основная поверхность, и внеэкранное изображение, используемое для двойной буферизации, обычно упоминается как задний буфер. Действие копирования содержания от одной поверхности до другого часто упоминается как блочная передача строки, или блитирующий (blt обычно объявляется «копированием битового массива» и не должен быть перепутан с тестовой системой BLT).

Основной поверхностью обычно управляют через графический объект любого компонента показа; когда в полноэкранном режиме, любая работа, используя графику полноэкранного окна является непосредственным управлением памятью для хранения содержимого экрана. Поэтому можно использовать в своих интересах другие возможности в полноэкранном монопольном режиме, который может иначе быть недоступным из-за издержек системы управления окнами. Один такой метод, который только доступен в полноэкранном монопольном режиме, является формой двойной буферизации, названной зеркальным отражением страницы.

Зеркальное отражение страницы

У многих видеокарт есть понятие видео указателя, который является просто адресом в видеопамяти. Этот указатель говорит видеокарту, где искать содержание видео, которое будет выведено на экран во время следующего цикла обновления. В некоторых видеокартах и на некоторых операционных системах, этим указателем можно даже управлять программно. Предположите, что Вы создали задний буфер (в видеопамяти) точного width, height, и битовой глубины экрана, затем потянули к тому буферу тот же самый путь, как Вы будете, используя двойную буферизацию. Теперь вообразите то, что произошло бы, если бы, вместо того, чтобы блитировать Ваше изображение на экран как в двойной буферизации, Вы просто изменили видео указатель на свой задний буфер. Во время следующего обновления видеокарта теперь использовала бы Ваше изображение, чтобы вывести на экран. Этот переключатель вызывают зеркальным отражением страницы, и увеличение производительности по blt-на-основе двойной буферизации — то, что только единственный указатель должен быть перемещен в память в противоположность копированию всего содержания от одного буфера до другого.

Когда зеркальное отражение страницы происходит, указатель на старый задний буфер теперь указывает на основную поверхность, и указатель на старую основную поверхность теперь указывает на заднюю буферную память. Это устанавливает Вас автоматически для следующей работы ничьей.

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

Преимущества Двойной буферизации и Зеркального отражения страницы

Если Ваша метрика производительности является просто скоростью, на которой двойная буферизация или зеркальное отражение страницы происходят против прямого рендеринга, Вы можете быть разочарованы. Можно найти, что Ваши числа для прямого рендеринга далеко превышают тех для двойной буферизации и что те числа далеко превышают тех для зеркального отражения страницы. Каждый из этих методов для используемого для того, чтобы улучшить воспринятую производительность, которая намного более важна в графических приложениях чем числовая производительность.

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

Что такое буферизация в java

Для оптимизации операций ввода-вывода используются буферизуемые потоки. Эти потоки добавляют к стандартным специальный буфер в памяти, с помощью которого повышается производительность при чтении и записи потоков.

Класс BufferedInputStream

Класс BufferedInputStream накапливает вводимые данные в специальном буфере без постоянного обращения к устройству ввода. Класс BufferedInputStream определяет два конструктора:

BufferedInputStream(InputStream inputStream) BufferedInputStream(InputStream inputStream, int bufSize)

Первый параметр — это поток ввода, с которого данные будут считываться в буфер. Второй параметр — размер буфера.

Например, буферизируем считывание данных из потока ByteArrayInputStream:

import java.io.*; public class Program < public static void main(String[] args) < String text = "Hello world!"; byte[] buffer = text.getBytes(); ByteArrayInputStream in = new ByteArrayInputStream(buffer); try(BufferedInputStream bis = new BufferedInputStream(in))< int c; while((c=bis.read())!=-1)< System.out.print((char)c); >> catch(Exception e) < System.out.println(e.getMessage()); >System.out.println(); > >

Класс BufferedInputStream в конструкторе принимает объект InputStream . В данном случае таким объектом является экземпляр класса ByteArrayInputStream .

Как и все потоки ввода BufferedInputStream обладает методом read() , который считывает данные. И здесь мы считываем с помощью метода read каждый байт из массива buffer.

Фактические все то же самое можно было сделать и с помощью одного ByteArrayInputStream, не прибегая к буферизированному потоку. Класс BufferedInputStream просто оптимизирует производительность при работе с потоком ByteArrayInputStream. Естественно вместо ByteArrayInputStream может использоваться любой другой класс, который унаследован от InputStream.

Класс BufferedOutputStream

Класс BufferedOutputStream аналогично создает буфер для потоков вывода. Этот буфер накапливает выводимые байты без постоянного обращения к устройству. И когда буфер заполнен, производится запись данных.

BufferedOutputStream определяет два конструктора:

BufferedOutputStream(OutputStream outputStream) BufferedOutputStream(OutputStream outputStream, int bufSize)

Первый параметр — это поток вывода, который унаследован от OutputStream, а второй параметр — размер буфера.

Рассмотрим на примере записи в файл:

import java.io.*; public class Program < public static void main(String[] args) < String text = "Hello world!"; // строка для записи try(FileOutputStream out=new FileOutputStream("notes.txt"); BufferedOutputStream bos = new BufferedOutputStream(out)) < // перевод строки в байты byte[] buffer = text.getBytes(); bos.write(buffer, 0, buffer.length); >catch(IOException ex) < System.out.println(ex.getMessage()); >> >

Класс BufferedOutputStream в конструкторе принимает в качестве параметра объект OutputStream — в данном случае это файловый поток вывода FileOutputStream. И также производится запись в файл. Опять же BufferedOutputStream не добавляет много новой функциональности, он просто оптимизирует действие потока вывода.

Что такое буферизация в java

Класс BufferedWriter записывает текст в поток, предварительно буферизируя записываемые символы, тем самым снижая количество обращений к физическому носителю для записи данных.

Класс BufferedWriter имеет следующие конструкторы:

BufferedWriter(Writer out) BufferedWriter(Writer out, int sz)

В качестве параметра он принимает поток вывода, в который надо осуществить запись. Второй параметр указывает на размер буфера.

Например, осуществим запись в файл:

import java.io.*; public class Program < public static void main(String[] args) < try(BufferedWriter bw = new BufferedWriter(new FileWriter("notes4.txt"))) < String text = "Hello World!\nHey! Teachers! Leave the kids alone."; bw.write(text); >catch(IOException ex) < System.out.println(ex.getMessage()); >> >

Чтение текста и BufferedReader

Класс BufferedReader считывает текст из символьного потока ввода, буферизируя прочитанные символы. Использование буфера призвано увеличить производительность чтения данных из потока.

Класс BufferedReader имеет следующие конструкторы:

BufferedReader(Reader in) BufferedReader(Reader in, int sz)

Второй конструктор, кроме потока ввода, из которого производится чтение, также определяет размер буфера, в который будут считываться символы.

Так как BufferedReader наследуется от класса Reader , то он может использовать все те методы для чтения из потока, которые определены в Reader. И также BufferedReader определяет свой собственный метод readLine() , который позволяет считывать из потока построчно.

Рассмотрим применение BufferedReader:

import java.io.*; public class Program < public static void main(String[] args) < try(BufferedReader br = new BufferedReader (new FileReader("notes4.txt"))) < // чтение посимвольно int c; while((c=br.read())!=-1)< System.out.print((char)c); >> catch(IOException ex) < System.out.println(ex.getMessage()); >> >

Также можно считать текст построчно:

try(BufferedReader br = new BufferedReader(new FileReader(«notes4.txt»))) < //чтение построчно String s; while((s=br.readLine())!=null)< System.out.println(s); >> catch(IOException ex)

Считывание с консоли в файл

Соединим оба класса BufferedReader и BufferedWriter для считывания с консоли в файл. Для этого определим следующий код программы:

import java.io.*; public class Program < public static void main(String[] args) < try(BufferedReader br = new BufferedReader (new InputStreamReader(System.in)); BufferedWriter bw = new BufferedWriter(new FileWriter("notes5.txt"))) < // чтение построчно String text; while(!(text=br.readLine()).equals("ESC"))< bw.write(text + "\n"); bw.flush(); >> catch(IOException ex) < System.out.println(ex.getMessage()); >> >

Здесь объект BufferedReader устанавливается для чтения с консоли с помощью объекта new InputStreamReader(System.in) . В цикле while считывается введенный текст. И пока пользователь не введет строку «ESC», объект BufferedWriter будет записывать текст файл.

3.15. Java примеры – Как буферизовать строки методом emit()

В следующем примере строки буферизуются и сбрасываются с помощью метода emit().

public class StringBuffer < public static void main(String[] args) < countTo_N_Improved(); >private final static int MAX_LENGTH = 30; private static String buffer = ""; private static void emit(String nextChunk) < if(buffer.length() + nextChunk.length() >MAX_LENGTH) < System.out.println(buffer); buffer = ""; >buffer += nextChunk; > private static final int N = 100; private static void countTo_N_Improved() < for (int count = 2; count > > 

Результат

Вышеприведенный пример кода даст следующий результат:

2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 

StringBuffer

Классы StringBuffer и StringBuilder используются для создания изменяемой строки.

public class HelloWorld < public static void main(String []args) < StringBuffer sb = new StringBuffer("привет"); sb.append("мир"); sb.insert(0, " ProgLang"); System.out.print(sb); >> 

Результат

Вышеприведенный пример кода даст следующий результат:

ProgLangприветмир 

Оглавление

  • 1. Java примеры – Использование кода на практике
  • 2. Java примеры – Окружающая среда
  • 2.1. Java примеры – Скомпилировать файл
  • 2.2. Java примеры – Установить путь к нескольким классам
  • 2.3. Java примеры – Отладка java-файла
  • 2.4. Java примеры – Установить путь к классу
  • 2.5. Java примеры – Просмотреть текущий путь класса
  • 2.6. Java примеры – Установить назначение файла класса
  • 2.7. Java примеры – Запустить скомпилированный java-файл класса
  • 2.8. Java примеры – Узнать версию Java
  • 2.9. Java примеры – Установить путь к классу в .jar-файле или .zip-файле
  • 3. Java примеры – Строки
  • 3.1. Java примеры – Сравнить две строки
  • 3.2. Java примеры – Найти последнее вхождение подстроки внутри подстроки
  • 3.3. Java примеры – Удалить нужный символ из строки
  • 3.4. Java примеры – Заменить символ в строке
  • 3.5. Java примеры – Вывод в обратном порядке
  • 3.6. Java примеры – Нахождение символа или слова в строке
  • 3.7. Java примеры – Разбиение строки на слова и символы
  • 3.8. Java примеры – Преобразование строки в верхний регистр
  • 3.9. Java примеры – Найти слово в строке
  • 3.10. Java примеры – Сравнить производительность создания строки
  • 3.11. Java примеры – Оптимизировать создание строк
  • 3.12. Java примеры – Форматирование строк
  • 3.13. Java примеры – Конкатенация строк
  • 3.14. Java примеры – Определить код Юникода символа в строке
  • 3.15. Java примеры – Буферизация строк
  • 4. Java примеры – Массивы
  • 4.1. Java примеры – Сортировка массива и поиск элемента
  • 4.2. Java примеры – Метод сортировки массива, вставить элемент в массив
  • 4.3. Java примеры – Размер двумерного массива
  • 4.4. Java примеры – Обратный порядок массива, переворачиваем массив
  • 4.5. Java примеры – Как выводить массивы и двумерные массивы в консоль
  • 4.6. Java примеры – Найти максимальный и минимальный элемент массива
  • 4.7. Java примеры – Соединить два массива в один
  • 4.8. Java примеры – Как заполнить массив числами
  • 4.9. Java примеры – Увеличить массив после инициализации
  • 4.10. Java примеры – Сравнение двух массивов
  • 4.11. Java примеры – Удаление элемента из массива
  • 4.12. Java примеры – Удаление массива из другого массива
  • 4.13. Java примеры – Одинаковые элементы массивов
  • 4.14. Java примеры – Поиск в массиве
  • 4.15. Java примеры – Равенство двух массивов
  • 4.16. Java примеры – Сравнить массивы
  • 5. Java примеры – Дата и время
  • 5.1. Java примеры – Форматирование времени в формате AM-PM
  • 5.2. Java примеры – Получение названия и номера текущего месяца
  • 5.3. Java примеры – Получить текущее время в часах и минутах
  • 5.4. Java примеры – Вывести текущее время и дату
  • 5.5. Java примеры – Вывести текущее время в 24-часовом формате
  • 5.6. Java примеры – Получить текущий месяц
  • 5.7. Java примеры – Получить текущие секунды
  • 5.8. Java примеры – Получить короткое название месяца
  • 5.9. Java примеры – Получить день недели
  • 5.10. Java примеры – Добавление времени к дате
  • 5.11. Java примеры – Отображение времени в формате другой страны
  • 5.12. Java примеры – Отображение времени на разных языках
  • 5.13. Java примеры – Прокрутить часы и месяцы
  • 5.14. Java примеры – Получить номер недели и месяц в году
  • 5.15. Java примеры – Форматы текущей даты
  • 6. Java примеры – Методы
  • 6.1. Java примеры – Перезагрузка методов
  • 6.2. Java примеры – Вывод массива с использованием метода
  • 6.3. Java примеры – Решение Ханойской башни
  • 6.4. Java примеры – Последовательность чисел Фибоначчи
  • 6.5. Java примеры – Вычисление факториала числа
  • 6.6. Java примеры – Переопределение метода
  • 6.7. Java примеры – Вывод массива с использованием метода
  • 6.8. Java примеры – Использование оператора break
  • 6.9. Java примеры – Использование оператора continue
  • 6.10. Java примеры – Использование метки в методе
  • 6.11. Java примеры – Использование операторов enum и switch
  • 6.12. Java примеры – Использование конструктора enum

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *