Berbagi teknologi

Literasi lengkap dalam model jaringan Java

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Ringkasan

Menjelaskan pengetahuan dasar NIO pada level ava, untuk tinjauan dasar

1. Ikhtisar NIO

Di Java, NIO (Non-blocking I/O atau New I/O) adalah kumpulan API operasi input/output baru yang diperkenalkan di Java SE 1.4 dan versi berikutnya.

Dibandingkan dengan model IO tradisional, model ini memberikan efisiensi lebih tinggi dan kemampuan pemrosesan bersamaan yang lebih baik. Fitur utama NIO adalah fitur non-pemblokirannya, yang memungkinkan satu thread mengelola beberapa saluran I/O, sehingga sangat meningkatkan kinerja aplikasi dalam skenario konkurensi tinggi.

Skenario penggunaan Java NIO sangat cocok untuk situasi di mana sejumlah besar koneksi bersamaan perlu diproses. Misalnya, di server jaringan, satu thread dapat mengelola ribuan koneksi klien tanpa perlu mengalokasikan thread independen untuk setiap koneksi . Dapat secara signifikan mengurangi konsumsi sumber daya sistem dan meningkatkan kemampuan pemrosesan

2. Tiga komponen utama NIO di Java

1. Saluran

Saluran adalah media aliran data di Java NIO. Bersifat dua arah dan dapat digunakan untuk membaca data atau menulis data. Keuntungan utama saluran adalah non-pemblokiran, artinya satu thread dapat mengelola beberapa saluran. Ketika tidak ada kejadian yang terjadi pada saluran, thread tidak akan diblokir dan malah dapat menangani tugas lainnya. Jenis saluran utama meliputi:

  • FileChannel: Digunakan untuk operasi membaca dan menulis file. Dapat digunakan untuk menulis data dari buffer ke file, atau untuk membaca data dari file ke buffer.
  • SocketChannel: Digunakan untuk koneksi TCP dalam komunikasi jaringan, dan dapat digunakan untuk membaca dan menulis data.
  • ServerSocketChannel: Digunakan untuk menerima koneksi SocketChannel baru, mirip dengan ServerSocket tradisional.
  • DatagramChannel: Digunakan untuk komunikasi UDP, yang dapat mengirim dan menerima datagram.

2. Penyangga

​Buffer adalah objek yang digunakan untuk menyimpan data di NIO. Ini adalah array byte yang dapat menulis data dan membaca data darinya. Buffer memiliki kapasitas tertentu dan memiliki dua properti penting: posisi dan batas.

  • Kapasitas: Jumlah maksimum elemen yang dapat disimpan oleh buffer.
  • Posisi: Indeks elemen yang sedang dioperasikan, yang berubah ketika data dibaca atau ditulis.
  • Membatasi: Dalam mode baca, nilai maksimum yang dapat dicapai oleh posisi; dalam mode tulis, posisi tidak boleh melebihi nilai tersebut.

Jenis buffer utama adalahByteBufferCharBufferShortBufferIntBufferLongBufferFloatBufferDanDoubleBuffer, setiap tipe berhubungan dengan tipe data primitif.

3. Penyeleksi

Selector adalah multiplexer di NIO yang memungkinkan satu thread memantau peristiwa dari berbagai saluran, seperti membaca, menulis, menghubungkan, dan menerima peristiwa. Pemilih memberi tahu aplikasi ketika salah satu saluran siap untuk operasi I/O. Penggunaan penyeleksi sangat meningkatkan kemampuan pemrosesan konkurensi aplikasi jaringan karena tidak perlu membuat thread untuk setiap koneksi.

Metode utama penyeleksi meliputi:

  • select(): Memblokir hingga setidaknya satu saluran siap untuk operasi I/O.
  • selectedKeys(): Mengembalikan Set yang berisi objek SelectionKey dari semua saluran yang disiapkan.
  • wakeup(): Interupsi diblokirselect()transfer.

SelectionKeyIni adalah hubungan antara penyeleksi dan saluran. Ini mewakili status pendaftaran saluran pada pemilih, termasuk saluran, penyeleksi, koleksi acara yang diminati, dan koleksi acara siap pakai.

3. Pemrograman jaringan

1. Memblokir I/O

​ Ini adalah model I/O paling tradisional. Di Java, Socket dan ServerSocket API tradisional didasarkan pada pemblokiran I/O. Dalam mode ini, ketika thread memulai operasi baca atau tulis, thread diblokir hingga operasi I/O selesai. Jika tidak ada data yang perlu dibaca untuk operasi baca, atau operasi tulis tidak dapat segera diselesaikan, thread akan menunggu hingga operasi selesai.

Fitur:

  • Model pemrograman sederhana: Mudah dipahami dan diterapkan.
  • Pekerjaan sumber daya: Setiap koneksi memerlukan thread independen, sehingga menghasilkan jumlah thread yang terbatas dan konsumsi sumber daya yang tinggi.
  • Batasan kinerja: Dalam skenario konkurensi tinggi, peralihan thread dan peralihan konteks memakan biaya yang mahal dan dapat dengan mudah menjadi hambatan.

2. I/O Tanpa Pemblokiran

​ I/O non-pemblokiran adalah bagian dari kerangka Java NIO (I/O Baru), yang memungkinkan thread memulai operasi baca dan tulis tanpa diblokir. Jika tidak ada data yang perlu dibaca untuk operasi baca, atau operasi tulis tidak dapat segera diselesaikan, thread tidak akan ditangguhkan dan dapat terus melakukan tugas lainnya.

Fitur:

  • fleksibilitas: Thread dapat menangani lebih banyak koneksi karena tidak diblokir saat menunggu operasi I/O.
  • Peningkatan kompleksitas: Pemrogram perlu memeriksa secara eksplisit apakah operasi telah selesai, yang meningkatkan kesulitan pemrograman.
  • Peningkatan kinerja: Dalam skenario konkurensi tinggi, overhead yang disebabkan oleh peralihan thread dapat dikurangi secara signifikan.

3. Multipleksing

Multiplexing adalah memantau beberapa deskriptor file secara bersamaan melalui satu thread, dan hanya beroperasi pada deskriptor jika sudah siap (biasanya berarti data dapat dibaca, atau buffer tulis dapat ditulis). Selector digunakan di Java untuk mengimplementasikan multiplexing.

Fitur:

  • Konkurensi tinggi: Satu thread dapat menangani ribuan koneksi, sehingga sangat meningkatkan throughput server.
  • Efisien: Hanya ketika operasi I/O siap, thread akan dibangunkan untuk menghindari peralihan thread yang tidak perlu.
  • Penghematan sumber daya: Dibandingkan dengan pemblokiran I/O, server dengan model multiplexing dapat memanfaatkan sumber daya sistem dengan lebih efisien.

Melihat:

Dalam aplikasi praktis, I/O non-blocking sering digunakan bersamaan dengan multiplexing. Misalnya, server dapat menggunakan Selector untuk memantau beberapa SocketChannel. Ketika SocketChannel memiliki data yang dapat dibaca atau ditulis, Selector akan memberi tahu server, dan server akan memproses SocketChannel khusus ini dengan cara yang tidak memblokir.

4.NIO VS BIO

4.1 aliran vs saluran

Di Java, Stream dan Channel adalah dua cara berbeda dalam memproses aliran data. Keduanya masing-masing termasuk dalam perpustakaan IO standar dan perpustakaan NIO. Berikut perbandingan detail kedua konsep tersebut:

Sungai kecil

Stream adalah bagian dari model IO (blocking IO) standar Java, yang menyediakan cara untuk membaca dan menulis data secara berurutan. Aliran dibagi menjadi dua jenis: InputStream dan OutputStream, yang masing-masing digunakan untuk membaca dan menulis data.Aliran ini dapat berupa aliran byte (sepertiInputStream, OutputStream) atau aliran karakter (sepertiReader, Writer)。

Fitur:

  • Obstruktif: Secara default, operasi aliran diblokir, artinya, jika tidak ada data untuk dibaca dalam operasi baca, atau operasi tulis tidak dapat segera diselesaikan, thread pemanggil akan diblokir hingga operasi selesai.
  • Keunikan: Setiap Aliran mempunyai arah, baik baca-saja atau tulis-saja.
  • mati otomatis: Setelah menggunakan Stream, Anda biasanya perlu memanggilnyaclose() metode untuk melepaskan sumber daya.Mulai dari Java 7, pernyataan try-with-resources dapat menutup implementasi secara otomatisAutoCloseableSumber daya antarmuka, termasuk Stream.

Saluran

Saluran adalah bagian dari model Java NIO (IO Baru), yang memberikan tingkat abstraksi lebih tinggi daripada Stream, sehingga memungkinkan pemrosesan data lebih efisien. Saluran bisa bersifat dua arah, artinya dapat digunakan untuk membaca dan menulis data.Jenis Saluran utama meliputiFileChannelSocketChannelServerSocketChannelDanDatagramChannel

Fitur:

  • non-pemblokiran :Saluran dapat dikonfigurasi dalam mode pemblokiran atau non-pemblokiran. Dalam mode non-pemblokiran, jika operasi baca tidak memiliki data untuk dibaca, atau operasi tulis tidak dapat segera diselesaikan, operasi akan segera kembali dan bukannya memblokir thread.
  • Operasi penyangga:Operasi saluran selalu dilakukan melalui buffer (Buffer). Data dibaca dari saluran ke buffer atau ditulis dari buffer ke saluran.
  • Multipleksing: Saluran dapat digunakan bersama dengan Selector untuk mencapai multiplexing, memungkinkan satu thread memantau operasi I/O beberapa Saluran dan meningkatkan kemampuan pemrosesan secara bersamaan.

Meringkaskan

  • Adegan yang berlaku: Stream lebih cocok untuk memproses kumpulan data yang lebih kecil atau operasi file sederhana, sedangkan Channel lebih cocok untuk memproses data dalam jumlah besar, terutama komunikasi jaringan dan operasi file besar, karena memberikan kinerja yang lebih tinggi dan kemampuan konkurensi yang lebih baik.
  • Kompleksitas pemrograman: API Stream relatif sederhana dan mudah digunakan; sedangkan API Channel dan NIO lebih kompleks, namun memberikan fungsi yang lebih kuat dan efisiensi yang lebih tinggi.
  • Pengelolaan sumber daya: Baik itu Aliran atau Saluran, sumber daya harus dikelola dengan tepat dan memastikan bahwa sumber daya tersebut ditutup ketika tidak lagi diperlukan untuk menghindari kebocoran sumber daya.

4.2

Di Java, model operasi I/O dapat diklasifikasikan berdasarkan dua dimensi yaitu sinkron/asinkron dan pemblokiran/non-pemblokiran.

4.2.1 I/O Pemblokiran Sinkron

definisi : I/O pemblokiran sinkron adalah model I/O paling tradisional. Saat thread memanggil operasi I/O (seperti membaca atau menulis), thread akan diblokir hingga operasi selesai. Ini berarti thread tidak dapat melakukan tugas lain apa pun hingga operasi selesai.

Fitur

  • Sederhana dan mudah digunakan, logika kodenya jelas.
  • Setiap operasi I/O memerlukan thread eksklusif, yang tidak cocok untuk skenario konkurensi tinggi dan dapat menyebabkan habisnya sumber daya thread.
  • Biasa digunakan diInputStreamOutputStreamSocketDanServerSocketpemandangan.

Contoh:

Gunakan tradisionalInputStreamDanOutputStreamUntuk membaca dan menulis file:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class SyncBlockingIOExample {
    public static void main(String[] args) {
        try (FileInputStream fis = new FileInputStream("input.txt");
             FileOutputStream fos = new FileOutputStream("output.txt")) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, bytesRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

4.2.2 I/O Non-Pemblokiran Sinkron

definisi : Dalam I/O non-pemblokiran sinkron, thread tidak akan diblokir setelah memanggil operasi I/O. Jika operasi tidak dapat segera diselesaikan, metode akan segera kembali, biasanya mengembalikan nilai khusus (seperti -1 atau 0) atau mengeluarkan pengecualian untuk menunjukkan bahwa operasi tidak selesai.

Fitur

  • Status operasi perlu disurvei hingga operasi selesai.
  • Pemanfaatan thread lebih tinggi karena thread dapat melakukan tugas lain sambil menunggu I/O.
  • Implementasinya lebih kompleks dan perlu menangani polling dan pemeriksaan status.
  • Berdasarkan Java NIOChannelsDanBuffers, dengan menyebutconfigureBlocking(false)Atur saluran ke mode non-pemblokiran.

Contoh:

Menggunakan NIOFileChannelUntuk membaca dan menulis tanpa pemblokiran:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.ByteBuffer;

public class SyncNonBlockingIOExample {
    public static void main(String[] args) {
        try (FileInputStream fis = new FileInputStream("input.txt");
             FileOutputStream fos = new FileOutputStream("output.txt");
             FileChannel inChannel = fis.getChannel();
             FileChannel outChannel = fos.getChannel()) {
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            inChannel.configureBlocking(false);
            while (inChannel.read(buffer) > 0) {
                buffer.flip();
                outChannel.write(buffer);
                buffer.clear();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

4.2.3 I/O Multipleksing Sinkron

definisi: Penggunaan model I/O multipleks sinkronSelector(pemilih) untuk memantau banyakChannel peristiwa.Saat utas memanggilSelector.select(), itu akan diblokir hingga setidaknya ada satuChannelPeristiwa (seperti dapat dibaca, dapat ditulis, permintaan koneksi, dll.) terjadi.

Fitur

  • Mengizinkan satu thread mengelola banyak threadChannel, meningkatkan konkurensi.
  • lulusSelectorDanSelectionKeyMekanisme yang secara efisien dapat menangani sejumlah besar koneksi bersamaan.
  • Cocok untuk skenario server jaringan, seperti server web dan server obrolan.
  • Berdasarkan kerangka Java NIO.

Contoh:

Menggunakan NIOFileChannelUntuk membaca dan menulis tanpa pemblokiran:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Set;

public class SyncMultiplexingIOExample {
    public static void main(String[] args) throws IOException {
        try (Selector selector = Selector.open();
             ServerSocketChannel serverSocketChannel = ServerSocketChannel.open()) {
            serverSocketChannel.socket().bind(new InetSocketAddress(8080));
            serverSocketChannel.configureBlocking(false);
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
            while (true) {
                if (selector.select() > 0) {
                    Set<SelectionKey> keys = selector.selectedKeys();
                    for (SelectionKey key : keys) {
                        if (key.isAcceptable()) {
                            ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
                            SocketChannel clientChannel = ssc.accept();
                            clientChannel.configureBlocking(false);
                            clientChannel.register(selector, SelectionKey.OP_READ);
                        }
                    }
                    keys.clear();
                }
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

4.2.4 I/O Non-Pemblokiran Asinkron

definisi : Dalam model I/O non-pemblokiran asinkron, thread kembali segera setelah memulai operasi I/O tanpa menunggu operasi selesai. Ketika operasi selesai, thread akan diberitahu secara asinkron melalui fungsi panggilan balik atau pemberitahuan acara.

Fitur

  • Model I/O paling efisien, thread tidak diblokir sama sekali dan dapat melakukan tugas lain dengan segera.
  • lulusAsynchronousChannelAntarmuka dan implementasi subkelasnya, sepertiAsynchronousFileChannelDanAsynchronousSocketChannel
  • Cocok untuk skenario konkurensi tinggi dan kinerja tinggi, seperti pemrosesan data besar dan server jaringan beban tinggi.
  • Java 7 memperkenalkan model I/O non-pemblokiran asinkron.

Contoh:

Menggunakan NIOAsynchronousFileChannelLakukan pembacaan dan penulisan file asinkron:

import java.io.IOException;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.ByteBuffer;
import java.util.concurrent.CountDownLatch;

public class AsyncNonBlockingIOExample {
    public static void main(String[] args) throws IOException, InterruptedException {
        AsynchronousFileChannel inChannel = AsynchronousFileChannel.open(Paths.get("input.txt"), StandardOpenOption.READ);
        AsynchronousFileChannel outChannel = AsynchronousFileChannel.open(Paths.get("output.txt"), StandardOpenOption.WRITE);
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        CountDownLatch latch = new CountDownLatch(1);
        inChannel.read(buffer, 0, buffer, 0, (channel, result) -> {
            buffer.flip();
            outChannel.write(buffer, 0, buffer, 0, null);
            latch.countDown();
        });
        latch.await();
        inChannel.close();
        outChannel.close();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

Catatan: Model asinkron memerlukan dukungan dari sistem operasi yang mendasarinya (Kernel)

  • Sistem Windows mengimplementasikan IO asinkron yang sebenarnya melalui IOCP
  • IO asinkron di sistem Linux diperkenalkan pada versi 2.6, tetapi implementasi dasarnya masih menggunakan multiplexing untuk mensimulasikan IO asinkron, dan tidak ada keunggulan kinerja.

4.2.5 I/O Pemblokiran Asinkron

definisi : Secara teori, model ini tidak ada, karena "asinkron" berarti operasi dilakukan di latar belakang dan thread tidak diblokir. Oleh karena itu, pemblokiran I/O asinkron adalah konsep yang kontradiktif dan tidak akan muncul dalam praktik.

4.2.6 Ringkasan

Memilih model I/O yang tepat sangat penting untuk kinerja dan pengelolaan sumber daya. Dalam skenario konkurensi tinggi, model I/O non-pemblokiran sinkron atau I/O multipleks sinkron adalah pilihan umum. Dalam skenario yang memerlukan performa dan kecepatan respons ekstrem, model I/O non-pemblokiran asinkron adalah pilihan pertama.

4.3 Nol salinan

Konsep Nol-Salinan

​Teknologi zero-copy berarti selama proses transmisi data dari satu tempat ke tempat lain, data tidak perlu disalin antara ruang pengguna dan ruang kernel, atau setidaknya mengurangi jumlah salinan tersebut, sehingga meningkatkan efisiensi sistem. Dalam operasi I/O tradisional, ketika data dibaca dari jaringan atau disk, data tersebut terlebih dahulu disalin ke buffer di ruang kernel, dan kemudian disalin dari ruang kernel ke buffer di ruang pengguna. Sebaliknya, dalam zero-copy, data dapat diproses langsung di ruang kernel, atau langsung ditransfer dari ruang kernel ke perangkat jaringan, sehingga mengurangi operasi penyalinan CPU, mengurangi overhead sistem, dan meningkatkan efisiensi transmisi data.

Sumber salinan nol

Konsep zero copy pertama kali muncul dalam desain sistem operasi, yang bertujuan untuk mengatasi hambatan kinerja yang disebabkan oleh penyalinan data dalam operasi I/O tradisional. Pada sistem komputer awal, semua operasi I/O memerlukan banyak salinan data di ruang pengguna dan ruang kernel. Hal ini secara bertahap menjadi hambatan kinerja setelah jaringan berkecepatan tinggi dan disk berkapasitas besar menjadi umum.

Poin teknis utama

  • I/O langsung: Mengizinkan aplikasi mengakses perangkat disk secara langsung, melewati mekanisme cache sistem file.
  • Pemetaan memori (MMAP): Memetakan file ke memori sehingga data file dapat diakses seperti memori, sehingga mengurangi penyalinan.
  • Kirim file: Panggilan sistem Linux yang dapat mentransfer data secara langsung dari satu deskriptor file ke deskriptor file lainnya, menghindari salinan perantara.
  • DMA (Akses Memori Langsung): Teknologi tingkat perangkat keras yang memungkinkan data ditransfer secara langsung antara perangkat dan memori tanpa keterlibatan CPU.

Implementasi di Jawa:

Java mendukung teknologi zero-copy melalui kerangka NIO (New I/O). NIO diperkenalkanFileChannelDanSocketChannel dan kelas lain, yang menyediakan operasi I/O yang lebih efisien. Secara khusus,FileChannel.transferTo()DanFileChannel.transferFrom()Metode dapat mentransfer data secara langsung dari saluran file ke saluran soket atau sebaliknya tanpa memuat data ke dalam buffer, sehingga mencapai nol salinan.

Misalnya, Anda perlu mengirim konten file besar ke jaringan. Pendekatan tradisional adalah membaca konten file terlebih dahulu ke dalam buffer dan kemudian menulis konten buffer ke jaringan. Ini melibatkan dua operasi penyalinan: satu dari disk ke buffer dan satu lagi dari buffer ke jaringan.saat menggunakantransferTo()Saat menggunakan metode ini, data dapat ditransfer langsung dari disk ke jaringan tanpa memerlukan buffer perantara, sehingga mengurangi jumlah salinan dan mencapai nol salinan.

Contoh penggunaan ByteBuffer:

ByteBufferdan lainnyaBufferkelas (misalnyaCharBufferShortBufferdll.) menyediakan buffer yang dapat diisi atau dikosongkan tanpa secara langsung melibatkan salinan antara ruang pengguna dan ruang kernel.ByteBufferDapat digunakan secara langsung atau tidak langsung dalam teknologi zero-copy:

  1. Penyangga LangsungByteBuffer.allocateDirect(size)DibuatByteBuffer Instance dipetakan langsung ke memori fisik, melewati heap Java.Ketika buffer tersebut dibandingkan denganFileChannelatauSocketChannel Ketika digunakan bersama-sama, data dapat ditransfer secara langsung antara memori fisik dan perangkat keras tanpa memerlukan salinan tambahan melalui heap Java. Hal ini memungkinkan zero-copy yang sebenarnya pada beberapa platform.
  2. menggunakanFileChanneldaritransferTo()DantransferFrom(): Metode ini memungkinkan data disimpan secara langsungFileChannelDanSocketChannelditransmisikan antaraByteBuffer sebagai perantara. Artinya data dapat ditransfer langsung dari disk ke jaringan atau sebaliknya tanpa harus disalin antara ruang pengguna dan ruang kernel.
  3. menggunakanByteBufferdariwrap()metodewrap()Metode ini memungkinkan Anda untuk menggabungkan array byte yang ada atau buffer lain ke dalam aByteBuffer , jadi tidak perlu menyalin data ke buffer baru. Hal ini berguna untuk menghindari penyalinan data yang tidak diperlukan.
  4. menggunakanByteBufferdarislice()metodeslice() metode membuat tampilan buffer tanpa menyalin data yang mendasarinya.Artinya besarByteBufferBagi menjadi beberapa buffer yang lebih kecil tanpa menyalin data.

Gabungkan ByteBuffer dengan FileChannel:

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;

public class ZeroCopyExample {
    public static void main(String[] args) {
        Path path = Path.of("example.txt");
        try (FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ)) {
            ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
            long transferred = fileChannel.transferTo(0, fileChannel.size(), System.out);
            System.out.println("Transferred bytes: " + transferred);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

Melihat:

Perlu dicatat bahwa pada kenyataannya, tidak ada salinan nol yang lengkap. Salinan nol yang disebutkan di sini hanya untuk aplikasi kita sendiri, yang tidak memiliki salinan tingkat pengguna. Tetapi bahkan di tingkat pengguna, tidak mungkin untuk tidak melakukan operasi penyalinan sama sekali, tetapi untuk mengurangi salinan sebanyak mungkin. Oleh karena itu, kita dapat memahami bahwa istilah zero copy sebenarnya mengacu pada teknologi pengurangan jumlah salinan data. dan itu tidak berarti bahwa tidak ada operasi penyalinan yang sebenarnya.