Чтение онлайн

на главную - закладки

Жанры

Философия Java3

Эккель Брюс

Шрифт:

Напрямую взаимодействует с каналом только буфер Byte Buffer, то есть буфер, хранящий простые байты. Если вы просмотрите документацию JDK для класса java.nio.ByteBuffer, то увидите что он достаточно прост: вы создаете его, указывая, сколько места надо выделить под данные. Класс содержит набор методов для получения и помещения данных в виде последовательности байтов или в виде примитивов. Однако возможности записать в него объект или даже простую строку нет. Буфер работает на достаточно низком уровне, поскольку обеспечивается более эффективная совместимость с большинством операционных систем.

Три

класса из «старой» библиотеки ввода/вывода были изменены так, чтобы они позволяли получить канал FileChannel: это FilelnputStream, FileOutput-Stream и RandomAccessFile. Заметьте, что эти классы манипулируют байтами, что согласуется с низкоуровневой направленностью nio. Классы для символьных данных Reader и Writer не образуют каналов, однако вспомогательный класс java.nio.channels.Channels имеет набор методов, позволяющих получить объекты Reader и Writer для каналов.

Простой пример использования всех трех типов потоков. Создаваемые каналы поддерживают запись, чтение/запись и только чтение:

//: io/GetChannel java // Получение каналов из потоков import java.nio.*, import java.nio channels *, import java io *;

public class GetChannel {

private static final int BSIZE = 1024; public static void main(String[] args) throws Exception { // Запись файла FileChannel fc =

new FileOutputStreamCdata.txt") getChannelО; fc write(ByteBuffer.wrap("Some text ".getBytesO)); fc. closeO,

// Добавление в конец файла fc =

new RandomAccessFileC'data.txt", "rw") getChannelО; fc position(fc.sizeO); // Переходим в конец fc write(ByteBuffer.wrap("Some more" getBytesO)), fc closeO; // Чтение файла;

fc = new FilelnputStreamC'data txt").getChannelО; ByteBuffer buff = ByteBuffer.allocate(BSIZE); fc.read(buff), buff .flipO;

while(buff .hasRemainingO)

System.out.print((char)buff getO);

}

} /* Output; Some text Some more *///:-

Для любого из рассмотренных выше классов потоков метод getChannel выдает канал FileChannel. Канал довольно прост: ему передается байтовый буфер ByteBuffer для чтения и записи, и вы можете заблокировать некоторые участки файла для монопольного доступа (этот процесс будет описан чуть позже).

Для помещения байтов в буфер ByteBuffer используется один из нескольких методов для записи данных (put); данные записываются в виде одного или нескольких байтов или значений примитивов. Впрочем, как было показано в примере, можно «заворачивать» уже существующий байтовый массив в буфер ByteBuffer, используя метод wrap. Когда вы так делаете, байтовый массив не копируется, а используется как хранилище для полученного буфера ByteBuffer. В таких случаях говорят, что буфер ByteBuffer создается на базе массива.

Файл data.txt заново открывается с помощью класса RandomAccessFile. Заметьте, что канал FileChannel может перемещаться внутри файла; в нашем примере он сдвигается в конец файла так, чтобы дополнительные записи присоединялись за существующим содержимым.

Чтобы доступ к файлу ограничивался только чтением, следует явно получить байтовый буфер ByteBuffer статическим методом allocate. Предназначение nio — быстрое перемещение большого количества данных, поэтому размер

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

Можно получить еще большее быстродействие, используя вместо метода allocate метод allocateDirect. Он производит буфер «прямого доступа», еще теснее привязанный к низкоуровневой работе операционной системы. Однако такой буфер требует больше ресурсов, а реализация его различается в различных операционных системах. Опять же, поэкспериментируйте со своим приложением и выясните, дадут ли буферы прямого доступа лучшую производительность.

После вызова метода read буфера FileChannel для сохранения байтов в буфере ByteBuffer также необходимо вызвать для буфера метод flip, позволяющий впоследствии извлечь из буфера его данные (да, все это выглядит немного неудобно, но помните, что расчет делался на высокое быстродействие, поэтому все делается на низком уровне). И если затем нам снова понадобится буфер для чтения, придется вызывать перед каждым методом read метод clear. В этом нетрудно убедиться на примере простой программы копирования файлов:

//• io/ChannelCopy java

// Копирование файла с использованием каналов и буферов

// {Параметры Channel Copy java test txt}

import java nio *.

import java nio.channels *.

import java io *,

public class ChannelCopy {

private static final int BSIZE = 1024, public static void main(String[] args) throws Exception { if(args length != 2) {

System out println("параметры Источник Приемник"), System exit(l);

}

FileChannel

in = new FileInputStream(args[0]).getChannelО. out = new FileOutputStream(args[l]).getChannelО, ByteBuffer buffer = ByteBuffer.allocate(BSIZE); while(in read(buffer) != -1) {

buffer flipO; // Подготовка к записи out.write(buffer):

buffer.clear; // Подготовка к чтению

}

}

} /// ~

В программе создаются два канала FileChannel: для чтения и для записи. Выделяется буфер ByteBuffer, а когда метод FileChannel.read возвращает -1, это значит, что мы достигли конца входных данных (без сомнения, пережиток UNIX и С). После каждого вызова метода read, помещающего данные в буфер, метод flip подготавливает буфер так, чтобы информация из него могла быть извлечена методом write. После вызова write информация все еще хранится в буфере, поэтому метод clear перемещает все его внутренние указатели, чтобы буфер снова был способен принимать данные в методе read.

Впрочем, рассмотренная программа не лучшим образом выполняет копирование файлов. Специальные методы, transferTo и transferFrom, позволяют напрямую присоединить один канал к другому:

// io/TransferTo java

// Использование метода transferToO для соединения каналов // {Параметры TransferTo java TransferTo txt} import java nio channels.*, import java io *.

public class TransferTo {

public static void main(String[] args) throws Exception { if(args length != 2) {

System out printin("параметры источник приемник"), System exit(l).

Поделиться:
Популярные книги

Газлайтер. Том 8

Володин Григорий
8. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 8

На Ларэде

Кронос Александр
3. Лэрн
Фантастика:
фэнтези
героическая фантастика
стимпанк
5.00
рейтинг книги
На Ларэде

Охота на попаданку. Бракованная жена

Герр Ольга
Любовные романы:
любовно-фантастические романы
5.60
рейтинг книги
Охота на попаданку. Бракованная жена

Кай из рода красных драконов

Бэд Кристиан
1. Красная кость
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Кай из рода красных драконов

Хозяйка Проклятой Пустоши. Книга 2

Белецкая Наталья
2. Хозяйка Проклятой Пустоши
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Хозяйка Проклятой Пустоши. Книга 2

Безумный Макс. Поручик Империи

Ланцов Михаил Алексеевич
1. Безумный Макс
Фантастика:
героическая фантастика
альтернативная история
7.64
рейтинг книги
Безумный Макс. Поручик Империи

Потусторонний. Книга 2

Погуляй Юрий Александрович
2. Господин Артемьев
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Потусторонний. Книга 2

Чапаев и пустота

Пелевин Виктор Олегович
Проза:
современная проза
8.39
рейтинг книги
Чапаев и пустота

Солнечный корт

Сакавич Нора
4. Все ради игры
Фантастика:
зарубежная фантастика
5.00
рейтинг книги
Солнечный корт

Лютая

Шёпот Светлана Богдановна
Любовные романы:
любовно-фантастические романы
6.40
рейтинг книги
Лютая

Ведьмак (большой сборник)

Сапковский Анджей
Ведьмак
Фантастика:
фэнтези
9.29
рейтинг книги
Ведьмак (большой сборник)

Наследие Маозари 4

Панежин Евгений
4. Наследие Маозари
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Наследие Маозари 4

Ученик

Губарев Алексей
1. Тай Фун
Фантастика:
фэнтези
5.00
рейтинг книги
Ученик

Начальник милиции. Книга 5

Дамиров Рафаэль
5. Начальник милиции
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Начальник милиции. Книга 5