Потоки используются для приема передачи данных. Существует два основных вида потоков байтовыми и символьными:
Поэтому существует три вида классов:
1) InputStream & OutputStream -- это байтовые потоки.
2) Reader & Writer -- это символьные потоки.
Отличие между ними лежит в следующем - первые читают побайтово, вторые посимвольно (в зависимости от кодировки либо побайтово, либо подвобайтово), и возвращают из метод read(arr), соответсвенно либо массив byte, либо массив char.
Если пользоваться read() без аргументов, то и в первого класса и во второго будет возвращаться int, только вот у первого единички могут быть только в первых 8 битах. Int возвращается для того, чтобы можно было вернуть -1, что означает, что мы подошли к концу потока.
Выше описанные классы абстрактные. Cимвольные классы-потоки базируются(используют) на байтовых. Поэтому есть посредники(bridges), которые помогают превратить байтовые в символьные потоки:
InputStreamReader & OutputStreamWriter.
Дополнительный вид потоков:
BufferedReader & PrintWriter -- это строчные потоки.
Построчные потоки основаны на символьных, но считывают/записывают они не посимвольно, а построчно. При этом ридер на ходу разбирается с файлом какой используется признак окончиния строки в файле. Райтер же вставляет характерный признак для поточной среды (ОС).
Строчные потоки являются буферезированными.
Буферы это обвертки:
1) BufferedInputStream & BufferedOutputStream.
2) BufferedReader & BufferedWriter.
Буфер можно вручную сливать в райтере, не дожидаясь его переполнения. Метод называется flush, а впринципе есть в любом райтере, но вызывать его смысл есть только в буферизированном райтере. У некоторых б-райтеров есть автофлешинг. Например PrintWriter делает флеш при каждом
println() и format().
В ридере есть аналог, этой технологии -- это маркировка, мы можем на определенном байте поставить эту марку, а потом если мы считаем из буфера часть потока, но если из-за ошибки потеряем эту часть, мы можем вызвать reset() и буфер заполнится потерянными байтами, а на выходе будет наш маркированный.:)
Поэтому существует три вида классов:
1) InputStream & OutputStream -- это байтовые потоки.
2) Reader & Writer -- это символьные потоки.
Отличие между ними лежит в следующем - первые читают побайтово, вторые посимвольно (в зависимости от кодировки либо побайтово, либо подвобайтово), и возвращают из метод read(arr), соответсвенно либо массив byte, либо массив char.
Если пользоваться read() без аргументов, то и в первого класса и во второго будет возвращаться int, только вот у первого единички могут быть только в первых 8 битах. Int возвращается для того, чтобы можно было вернуть -1, что означает, что мы подошли к концу потока.
Выше описанные классы абстрактные. Cимвольные классы-потоки базируются(используют) на байтовых. Поэтому есть посредники(bridges), которые помогают превратить байтовые в символьные потоки:
InputStreamReader & OutputStreamWriter.
Дополнительный вид потоков:
BufferedReader & PrintWriter -- это строчные потоки.
Построчные потоки основаны на символьных, но считывают/записывают они не посимвольно, а построчно. При этом ридер на ходу разбирается с файлом какой используется признак окончиния строки в файле. Райтер же вставляет характерный признак для поточной среды (ОС).
BufferedReader inputStream = null;
PrintWriter outputStream = null;
try {
inputStream =
new BufferedReader(new FileReader("xanadu.txt"));
outputStream =
new PrintWriter(new FileWriter("characteroutput.txt"));
String l;
while ((l = inputStream.readLine()) != null) {
outputStream.println(l);
}
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
Использование напрямую потоков довольно дорогое удовольствие, потому что они обращаются напрямую к ОС, и та запускает дорогостоющие обращения к жестким дискам, к сетевому ресурсу и т.д. Продуктивней использовать буферизированные потоки, ридеры обращаются к ОС, если буфер пуст, а райтеры - если буфер полный. Буфер находится в оперативной памяти, в части выделенной под работающий поток.
Строчные потоки являются буферезированными.
Буферы это обвертки:
1) BufferedInputStream & BufferedOutputStream.
2) BufferedReader & BufferedWriter.
Буфер можно вручную сливать в райтере, не дожидаясь его переполнения. Метод называется flush, а впринципе есть в любом райтере, но вызывать его смысл есть только в буферизированном райтере. У некоторых б-райтеров есть автофлешинг. Например PrintWriter делает флеш при каждом
println() и format().
В ридере есть аналог, этой технологии -- это маркировка, мы можем на определенном байте поставить эту марку, а потом если мы считаем из буфера часть потока, но если из-за ошибки потеряем эту часть, мы можем вызвать reset() и буфер заполнится потерянными байтами, а на выходе будет наш маркированный.:)
Комментариев нет:
Отправить комментарий