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

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

Жанры

Программирование на Java

Вязовик Н.А.

Шрифт:

pipeOut.write((byte)(Math.random*127));

}

// Считать из потока доступные данные,

// добавить их к уже считанным.

int willRead = pipeIn.available;

if(willRead+countRead>toRead.length)

//Нужно считать только до предела массива

willRead = toRead.length-countRead;

countRead += pipeIn.read(toRead, countRead, willRead);

}

}

catch (IOException e) {

System.out.println ("Impossible IOException occur: ");

e.printStackTrace;

}

Пример 15.3.

Данный пример носит чисто демонстративный характер (в результате его работы массив toRead будет заполнен случайными числами). Более явно выгода от использования PipedI/OStream в основном проявляется при разработке многопоточного приложения. Если в программе запускается несколько потоков исполнения, организовать передачу данных между ними удобно с помощью этих классов. Для этого нужно создать связанные объекты PipedI/OStream, после чего передать ссылки на них в соответствующие потоки. Поток выполнения, в котором производится чтение данных, может содержать подобный код:

// inStream - объект класса PipedInputStream

try {

while(true) {

byte[] readedBytes = null;

synchronized(inStream) {

int bytesAvailable = inStream.available;

readedBytes = new byte[bytesAvailable];

inStream.read(readedBytes);

}

// обработка полученных данных из readedBytes

// …

} catch(IOException e) {

/* IOException будет брошено, когда поток inStream, либо

связанный с ним PipedOutputStream, уже закрыт, и при этом

производится попытка считывания из inStream */

System.out.println("работа с потоком inStream завершена");

}

Пример 15.4.

Если с объектом inStream одновременно могут работать несколько потоков выполнения, то необходимо использовать блок synchronized (как и сделано в примере), который гарантирует, что в период между вызовами inStream.available и inStream.read(…) ни в каком другом потоке выполнения не будет производиться считывание из inStream. Поэтому вызов inStream.read(readedBytes) не приведет к блокировке и все данные, готовые к считыванию, будут считаны.

StringBufferInputStream

Иногда бывает удобно работать с текстовой строкой String как с потоком байт. Для этого можно воспользоваться классом StringBufferInputStream. При создании объекта этого класса необходимо передать конструктору объект String. Данные, возвращаемые методом read, будут считываться именно из этой строки. При этом символы будут преобразовываться в байты с потерей точности – старший байт отбрасывается (напомним, что символ char состоит из двух байт).

SequenceInputStream

Класс SequenceInputStream объединяет поток данных из других двух и более входных потоков. Данные будут вычитываться последовательно – сначала все данные из первого потока в списке, затем из второго, и так далее. Конец потока SequenceInputStream будет достигнут только тогда, когда будет достигнут конец потока, последнего в списке.

В этом классе имеется два конструктора – принимающий два потока и принимающий Enumeration (в котором, конечно, должны быть только экземпляры InputStream и его наследников). Когда вызывается метод read, SequenceInputStream пытается считать байт из текущего входного потока. Если в нем больше данных нет (считанное из него значение равно -1 ), у него вызывается метод close и следующий входной поток становится текущим. Так продолжается до тех пор, пока не будут получены все данные из последнего потока. Если при считывании обнаруживается, что больше входных потоков нет, SequenceInputStream возвращает -1. Вызов метода close у SequenceInputStream закрывает все содержащиеся в нем входные потоки.

Пример:

FileInputStream inFile1 = null;

FileInputStream inFile2 = null;

SequenceInputStream sequenceStream = null;

FileOutputStream outFile = null; try {

inFile1 = new FileInputStream("file1.txt");

inFile2 = new FileInputStream("file2.txt");

sequenceStream = new SequenceInputStream(inFile1, inFile2);

outFile = new FileOutputStream("file3.txt");

int readedByte = sequenceStream.read;

while(readedByte!=-1) {

outFile.write(readedByte);

readedByte = sequenceStream.read;

}

}

catch (IOException e) {

System.out.println("IOException: " + e.toString);

}

finally {

try {

sequenceStream.close;

}

catch(IOException e) {

};

try {

outFile.close;

}

catch(IOException e) {};

}

Пример 15.5.

В результате выполнения этого примера в файл file3.txt будет записано содержимое файлов file1.txt и file2.txt – сначала полностью file1.txt, потом file2.txt. Закрытие потоков производится в блоке finally. Поскольку при вызове метода close может возникнуть IOException, необходим try-catch блок. Причем, каждый вызов метода close взят в отдельный try-catch блок - для того, чтобы возникшее исключение при закрытии одного потока не помешало закрытию другого. При этом нет необходимости закрывать потоки inFile1 и inFile2 – они будут автоматически закрыты при использовании в sequenceStream - либо когда в них закончатся данные, либо при вызове у sequenceStream метода close.

Объект SequenceInputStream можно было создать и другим способом: сначала получить объект Enumeration, содержащий все потоки, и передать его в конструктор SequenceInputStream:

Vector vector = new Vector;

vector.add(new StringBufferInputStream("Begin file1\n"));

vector.add(new FileInputStream("file1.txt"));

vector.add(new StringBufferInputStream("\nEnd of file1, begin file2\n"));

vector.add(new FileInputStream("file2.txt"));

vector.add(new StringBufferInputStream("\nEnd of file2"));

Enumeration en = vector.elements;

sequenceStream = new SequenceInputStream(en);

Пример 15.6.

Если заменить в предыдущем примере инициализацию sequenceStream на приведенную здесь, то в файл file3.txt, кроме содержимого файлов file1.txt и file2.txt, будут записаны еще три строки – одна в начале файла, одна между содержимым файлов file1.txt и file2.txt и еще одна в конце file3.txt.

Классы FilterInputStream и FilterOutputStream и их наследники

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

Протокол "Наследник"

Лисина Александра
1. Гибрид
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Протокол Наследник

Первый среди равных. Книга IX

Бор Жорж
9. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Первый среди равных. Книга IX

Алтарь

Жгулёв Пётр Николаевич
3. Real-Rpg
Фантастика:
фэнтези
7.00
рейтинг книги
Алтарь

Отряд

Валериев Игорь
5. Ермак
Фантастика:
альтернативная история
5.25
рейтинг книги
Отряд

Мужчина моей судьбы

Ардова Алиса
2. Мужчина не моей мечты
Любовные романы:
любовно-фантастические романы
8.03
рейтинг книги
Мужчина моей судьбы

Законы Рода. Том 4

Андрей Мельник
4. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 4

Инквизитор тьмы 3

Шмаков Алексей Семенович
3. Инквизитор Тьмы
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Инквизитор тьмы 3

Русич. Бей первым

Поселягин Владимир Геннадьевич
1. Русич
Фантастика:
фэнтези
5.25
рейтинг книги
Русич. Бей первым

Идеальный мир для Лекаря 22

Сапфир Олег
22. Лекарь
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Идеальный мир для Лекаря 22

Я снова граф. Книга XI

Дрейк Сириус
11. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я снова граф. Книга XI

Бомбардировщики. Полная трилогия

Максимушкин Андрей Владимирович
Фантастика:
альтернативная история
6.89
рейтинг книги
Бомбардировщики. Полная трилогия

#Бояръ-Аниме. Газлайтер. Том 11

Володин Григорий Григорьевич
11. История Телепата
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
#Бояръ-Аниме. Газлайтер. Том 11

Легионы во Тьме 2

Владимиров Денис
10. Глэрд
Фантастика:
боевая фантастика
фэнтези
попаданцы
5.00
рейтинг книги
Легионы во Тьме 2

Первый среди равных. Книга VII

Бор Жорж
7. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Первый среди равных. Книга VII