Как мы знаем, Java NIO является более оптимизированным API для операций ввода-вывода данных по сравнению с традиционным API ввода-вывода Java. Еще одна дополнительная поддержка, которую обеспечивает Java NIO, заключается в чтении / записи данных из / в несколько буферов в канал. Это многократное чтение и поддержка записи называется Scatter and Gather, в которой данные разбрасываются на несколько буферов из одного канала в случае чтения данных, в то время как данные собираются из нескольких буферов в один канал в случае записи данных.
Для достижения этого множественного чтения и записи из канала есть API ScatteringByteChannel и GatheringByteChannel, который Java NIO предоставляет для чтения и записи данных, как показано в примере ниже.
GatheringByteChannel
запись в несколько каналов — в этом мы сделали запись данных из нескольких буферов в один канал. Для этого снова несколько буферов выделяются и добавляются в массив типа буфера. Затем этот массив передается в качестве параметра методу write () метода GatheringByteChannel который затем записывает данные из нескольких буферов в той последовательности, в которой эти буферы находятся в массиве. Следует помнить, что здесь записываются только данные между положением и пределом буферов.
В следующем примере показано, как осуществляется сбор данных в Java NIO.
import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.GatheringByteChannel; public class GatherExample { private static String FILENAME = "C:/Test/temp.txt"; public static void main(String[] args) { String stream1 = "Gather data stream first"; String stream2 = "Gather data stream second"; ByteBuffer bLen1 = ByteBuffer.allocate(1024); ByteBuffer bLen2 = ByteBuffer.allocate(1024); // Next two buffer hold the data we want to write ByteBuffer bstream1 = ByteBuffer.wrap(stream1.getBytes()); ByteBuffer bstream2 = ByteBuffer.wrap(stream2.getBytes()); int len1 = stream1.length(); int len2 = stream2.length(); // Writing length(data) to the Buffer bLen1.asIntBuffer().put(len1); bLen2.asIntBuffer().put(len2); System.out.println("Gathering : Len1 = " + len1); System.out.println("Gathering : Len2 = " + len2); // Write data to the file try { FileOutputStream out = new FileOutputStream(FILENAME); GatheringByteChannel gather = out.getChannel(); gather.write(new ByteBuffer[] {bLen1, bLen2, bstream1, bstream2}); out.close(); gather.close(); } catch (FileNotFoundException exObj) { exObj.printStackTrace(); } catch(IOException ioObj) { ioObj.printStackTrace(); } } }
Выход
Gathering : Len1 = 24 Gathering : Len2 = 25
В заключение можно сделать вывод, что подход «разброс / сбор» в Java NIO представлен как оптимизированный и многозадачный при правильном использовании. Он позволяет делегировать операционной системе тяжелую работу по разделению прочитанных данных на несколько сегментов или сборке. Несопоставимые фрагменты данных в целом. Несомненно, это экономит время и более эффективно использует операционную систему за счет исключения буферных копий и уменьшения объема кода, необходимого для записи и отладки.