Rumah >Java >javaTutorial >Analisis perbandingan input dan output Java IO, NIO dan AIO

Analisis perbandingan input dan output Java IO, NIO dan AIO

王林
王林ke hadapan
2023-05-08 23:07:071615semak imbas

    1 Sejarah pembangunan Java I/O

    Analisis perbandingan input dan output Java IO, NIO dan AIO

    Java IO (Input/Output) ialah API. untuk membaca dan menulis data, ia menyediakan satu siri kelas dan antara muka untuk membaca dan menulis pelbagai jenis data. Berikut ialah pengenalan ringkas kepada sejarah pembangunan Java IO:

    • JDK 1.0 (1996) Java IO asal hanya menyokong strim bait (InputStream, OutputStream) dan strim aksara (Reader, Penulis) Dua jenis, berdasarkan model penyekatan IO (BIO).

    • JDK 1.1 (1997) JDK 1.1 memperkenalkan pakej NIO (IO Baharu), konsep yang disokong seperti penimbal dan saluran, dan menyediakan IO yang lebih cekap Mod operasi boleh merealisasikan IO yang tidak menyekat mod (NIO).

    • JDK 1.4 (2002) JDK 1.4 menambah API NIO.2, juga dikenali sebagai Java NIO dengan penimbal, menyediakan fungsi pemprosesan fail yang lebih berkuasa dan operasi IO yang lebih cekap.

    • JDK 7 (2011) JDK 7 memperkenalkan versi dipertingkat NIO.2 - NIO.2 dengan Completion Ports, juga dikenali sebagai AIO (Asynchronous IO), menyokong tak segerak Kaedah IO mempunyai kelebihan apabila mengendalikan sejumlah besar permintaan serentak.

    Berikut ialah perbezaan antara ketiga-tiga:

    Analisis perbandingan input dan output Java IO, NIO dan AIO

    • Menyekat IO (BIO) BIO ialah model IO asal Java, yang menggunakan kaedah menyekat untuk melaksanakan operasi membaca dan menulis data. Iaitu, apabila benang menjalankan operasi IO, jika tiada data untuk dibaca, benang akan menyekat dan menunggu sehingga ada data untuk dibaca atau tamat masa. BIO sesuai untuk mengendalikan senario di mana bilangan sambungan agak kecil dan tetap, tetapi keupayaan serentak tidak mencukupi.

    • NIO tidak menyekat (NIO) NIO ialah model IO baharu yang diperkenalkan dalam Java 1.4 Ia menggunakan mekanisme pemultipleks (Pemilih) untuk mengurus berbilang saluran pada masa yang sama melalui nombor yang kecil daripada utas , mencapai kesan satu utas memproses berbilang permintaan pada masa yang sama. NIO mempunyai konkurensi yang tinggi, daya pemprosesan yang tinggi dan kebolehpercayaan yang lebih tinggi, dan sesuai untuk mengendalikan senario dengan bilangan sambungan yang besar dan masa sambungan yang singkat.

    • Asynchronous IO (AIO) AIO ialah model IO yang disokong oleh Java 1.7 Ia menggunakan pendekatan dipacu peristiwa untuk membaca dan menulis data Apabila data sedia, ia dilakukan dalam fungsi panggil balik berurusan dengan. Tidak seperti NIO, operasi baca dan tulis AIO adalah tak segerak, dan tidak perlu membuat tinjauan pendapat untuk menyemak sama ada data sudah sedia. AIO sesuai untuk mengendalikan senario dengan bilangan sambungan yang besar, masa sambungan yang panjang dan banyak operasi baca dan tulis.

    2. Java IO

    2.1 Pengenalan

    Dalam pengaturcaraan Java, operasi IO (Input/Output) adalah operasi yang sangat biasa, yang melibatkan untuk membaca dan menulis fail, komunikasi rangkaian, dsb. Java menyediakan pelbagai kelas untuk menyokong operasi ini. Artikel ini akan bermula dengan pengetahuan asas IO dan secara beransur-ansur pergi ke mendalam untuk memperkenalkan semua aspek Java IO.

    2.2 Konsep asas

    2.2.1 Strim input dan strim output

    Dalam Java, strim input (InputStream) dan strim output (OutputStream) ialah dua jenis abstraksi yang penting. Aliran input mewakili sumber data input, yang boleh berupa fail, sambungan rangkaian, paip, dsb. Strim input dan strim output digunakan dengan cara yang sama, dengan mencipta objek strim dan kemudian menggunakan antara muka kaedah yang sepadan untuk melaksanakan operasi baca dan tulis.

    2.2.2 Strim bait dan strim aksara

    Operasi IO dalam Java juga boleh dibahagikan kepada dua jenis: strim bait dan strim aksara. Strim bait beroperasi dalam unit bait (bait) dan sesuai untuk memproses data binari, seperti imej, audio, dsb. manakala aliran aksara beroperasi dalam unit aksara (char) dan sesuai untuk memproses data teks, seperti fail teks, dsb. Di Java, strim bait dilaksanakan terutamanya oleh kelas InputStream dan OutputStream serta subkelasnya, manakala aliran aksara terutamanya dilaksanakan oleh kelas Pembaca dan Penulis serta subkelasnya.

    2.2.3 Aliran Penampan

    Apabila menjalankan operasi IO, kami mungkin perlu melakukan operasi membaca dan menulis yang kerap, dan membaca dan menulis yang kerap boleh menyebabkan masalah prestasi. Untuk menyelesaikan masalah ini, Java menyediakan aliran buffer (Buffered Stream) untuk meningkatkan kecekapan operasi IO. Aliran penimbal boleh mengurangkan bilangan akses kepada sumber asas melalui kawasan cache dalaman, dengan itu meningkatkan kecekapan membaca dan menulis data.

    2.3 Penggunaan Java IO

    2.3.1 Membaca dan menulis fail

    Membaca dan menulis fail dalam Java ialah salah satu operasi yang paling biasa dalam pembangunan. Berikut ialah contoh membaca kandungan fail dan mengeluarkannya:

        try (FileInputStream fis = new FileInputStream("test.txt");
             InputStreamReader isr = new InputStreamReader(fis);
             BufferedReader br = new BufferedReader(isr)) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    Dalam contoh ini, kami menggunakan kelas seperti FileInputStream, InputStreamReader dan BufferedReader untuk melengkapkan pembacaan fail. Mula-mula, kami mencipta objek aliran input melalui kelas FileInputStream dan menentukan nama fail yang akan dibaca, kemudian kami menggunakan InputStreamReader untuk menukar aliran bait kepada aliran aksara, dan kemudian menggunakan BufferedReader untuk membaca kandungan teks baris demi baris.

    Begitu juga, menulis fail dalam Java juga sangat mudah. ​​Berikut ialah contoh menulis fail:

    try (FileOutputStream fos = new FileOutputStream("test.txt");
         OutputStreamWriter osw = new OutputStreamWriter(fos);
         BufferedWriter bw = new BufferedWriter(osw)) {
        bw.write("Hello, world!");
    } catch (IOException e) {
        e.printStackTrace();
    }

    在这个示例中,我们使用了FileOutputStream、OutputStreamWriter和BufferedWriter等类来完成文件的写入。首先,我们通过FileOutputStream类创建了一个输出流对象,并指定了要写入的文件名称;然后通过OutputStreamWriter将字节流转换为字符流,再通过BufferedWriter实现按行写入文本内容。

    3、Java NIO

    3.1 简介

    Java NIO(New IO)是Java SE 1.4引入的一个新的IO API,它提供了比传统IO更高效、更灵活的IO操作。与传统IO相比,Java NIO的优势在于它支持非阻塞IO和选择器(Selector)等特性,能够更好地支持高并发、高吞吐量的应用场景。本文将从NIO的基础知识讲起,逐步深入,介绍Java NIO的各个方面。

    3.2 核心概念

    3.2.1 选择器(Selector)

    选择器是Java NIO中的一个重要组件,它可以用于同时监控多个通道的读写事件,并在有事件发生时立即做出响应。选择器可以实现单线程监听多个通道的效果,从而提高系统吞吐量和运行效率。

    3.2.2 通道(Channel)

    通道是一个用于读写数据的对象,类似于Java IO中的流(Stream)。与流不同的是,通道可以进行非阻塞式的读写操作,并且可以同时进行读写操作。通道分为两种类型:FileChannel和SocketChannel,分别用于文件和网络

    通信。

    3.2.3 缓冲区(Buffer)

    在Java NIO中,所有数据都是通过缓冲区对象进行传输的。缓冲区是一段连续的内存块,可以保存需要读写的数据。缓冲区对象包含了一些状态变量,例如容量(capacity)、限制(limit)、位置(position)等,用于控制数据的读写。

    3.3 Java NIO的使用

    3.3.1 缓冲区操作

    Java NIO中的缓冲区操作主要包括数据读取和数据写入两种操作。下面是一个简单的缓冲区读取示例:

    ByteBuffer buffer = ByteBuffer.allocate(1024);
    try (FileChannel channel = new FileInputStream("test.txt").getChannel()) {
        int bytesRead = channel.read(buffer);
        while (bytesRead != -1) {
            buffer.flip();
            while (buffer.hasRemaining()) {
                System.out.print((char) buffer.get());
            }
            buffer.clear();
            bytesRead = channel.read(buffer);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    在这个示例中,我们使用了FileChannel类和ByteBuffer类来完成文件的读取。首先,我们通过FileInputStream类创建了一个输入流对象,然后通过getChannel()方法获取到对应的通道对象;接着,我们创建了一个容量为1024字节的ByteBuffer对象,并调用read()方法从通道中读取数据,将读取到的数据保存在缓冲区中。读取完成后,我们通过flip()方法将缓冲区切换为读模式,并使用hasRemaining()和get()方法逐个读取数据;最后通过clear()方法清空缓冲区,准备进行下一轮读取。

    Java NIO中的缓冲区写操作也非常类似,下面是一个简单的缓冲区写入示例:

    ByteBuffer buffer = ByteBuffer.wrap("Hello, world!".getBytes());
    try (FileChannel channel = new FileOutputStream("test.txt").getChannel()) {
        channel.write(buffer);
    } catch (IOException e) {
        e.printStackTrace();
    }

    在这个示例中,我们使用了FileChannel类和ByteBuffer类来完成文件的写入。首先,我们通过ByteBuffer.wrap()方法将字符串转换为ByteBuffer对象;然后,我们通过FileOutputStream类创建了一个输出流对象,再通过getChannel()方法获取到对应的通道对象;接着,我们调用write()方法将缓冲区中的数据写入通道中,完成文件写入操作。

    3.3.2 通道操作

    Java NIO中的通道(Channel)是用于进行数据传输的对象。通道可以连接到源或目标节点,用于读取和写入数据。与传统的Java IO不同,NIO中的通道可以实现非阻塞式地读写数据,从而提高了应用程序的性能和并发处理能力。

    要使用通道进行读写操作,首先需要打开通道。Java NIO中有多种类型的通道,每种通道都提供了自己的打开方式。例如,要打开一个文件通道,可以通过FileInputStream或FileOutputStream对象获取对应的FileChannel对象,如下所示:

        FileChannel channel = new FileInputStream("file.txt").getChannel();

    读取数据 一旦打开了通道,就可以开始读取数据。在NIO中,数据通过缓冲区进行传输。要读取数据,需要将数据存储在缓冲区中,然后从缓冲区中读取数据。以下是一个简单的读取操作示例:

    ByteBuffer buffer = ByteBuffer.allocate(1024);
    // 从通道中读取数据
    int bytesRead = channel.read(buffer);
    while (bytesRead != -1) {
        // 切换为读模式
        buffer.flip();
        // 读取缓冲区中的数据
        while (buffer.hasRemaining()) {
            System.out.print((char) buffer.get());
        }
        // 清空缓冲区
        buffer.clear();
        bytesRead = channel.read(buffer);
    }

    在这个示例中,我们首先创建了一个容量为1024字节的ByteBuffer对象,并使用channel.read()方法从文件通道中读取数据。读取到数据后,我们将ByteBuffer切换为读模式,再使用hasRemaining()和get()方法逐个读取缓冲区中的数据。

    写入数据 要写入数据,也需要将数据存储在缓冲区中,然后将缓冲区中的数据写入到通道中。以下是一个简单的写入操作示例:

    ByteBuffer buffer = ByteBuffer.wrap("Hello, world!".getBytes());
    // 将数据写入通道
    channel.write(buffer);

    在这个示例中,我们首先使用ByteBuffer.wrap()方法将字符串转换为ByteBuffer对象,在通过channel.write()方法将ByteBuffer中的数据写入到通道中。

    4、Java AIO

    Java AIO(Asynchronous IO)是一种基于事件和回调的IO模型,相比Java BIO(Blocking IO)和Java NIO(Non-blocking IO),它具有更高的并发性、更高的吞吐量和更高的可靠性。本文将介绍Java AIO的原理、特点和应用。

    4.1 Prinsip Java AIO

    Java AIO menggunakan IO tak segerak untuk membaca dan menulis data Tidak seperti Java NIO, ia tidak perlu membuat tinjauan pendapat untuk menyemak sama ada data sudah sedia, tetapi sistem pengendalian Selesai. Apabila data sedia, sistem pengendalian akan memberitahu aplikasi dan mengendalikannya dalam fungsi panggil balik.

    AIO menggunakan tiga komponen teras: AsynchronousChannel, CompletionHandler dan
    AsynchronousServerSocketChannel. Antaranya, AsynchronousChannel ialah saluran untuk membaca/menulis data, CompletionHandler ialah kaedah panggil balik apabila operasi I/O selesai, dan AsynchronousServerSocketChannel ialah saluran soket sisi pelayan tak segerak yang digunakan untuk memantau permintaan sambungan pelanggan.

    Apabila data sedia, sistem pengendalian akan memberitahu aplikasi dan melaksanakan kaedah panggil balik dalam fungsi panggil balik apabila operasi I/O selesai. Ini mengelakkan situasi di mana benang disekat menunggu operasi I/O selesai, dengan itu meningkatkan kecekapan dan keupayaan pemprosesan serentak program.

    4.2 Ciri Java AIO

    • Konkurensi tinggi: Java AIO menggunakan IO tak segerak untuk operasi membaca dan menulis data, yang boleh mencapai keupayaan pemprosesan serentak yang tinggi.

    • Hasil tinggi: Java AIO menyokong operasi baca dan tulis tak segerak dan boleh mengendalikan berbilang permintaan pada masa yang sama, sekali gus meningkatkan kecekapan dan daya pemprosesan data membaca dan menulis.

    • Kebolehpercayaan tinggi: Oleh kerana Java AIO menggunakan IO tak segerak untuk membaca dan menulis data, ia boleh mengelakkan sekatan benang menunggu operasi I/O selesai, sekali gus meningkatkan kebolehpercayaan program.

    • Mudah digunakan: Java AIO menyediakan API yang ringkas dan mudah digunakan, dan anda boleh melaksanakan operasi IO tak segerak tanpa menulis kod kompleks.

    4.3 Aplikasi Java AIO

    Java AIO sesuai untuk senario yang memerlukan sejumlah besar sambungan serentak, tetapi setiap sambungan mempunyai sedikit interaksi data, seperti mesej- aplikasi berasaskan Program, panggilan prosedur jauh (RPC), dsb. Dalam senario aplikasi ini, AIO boleh meningkatkan prestasi dan keupayaan pemprosesan serentak program ini, dengan itu memenuhi keperluan pengguna untuk pemprosesan tinggi dan kependaman rendah.

    Selain itu, Java AIO juga boleh digunakan untuk membangunkan pelayan rangkaian berprestasi tinggi, seperti pelayan bilik sembang, pelayan permainan dalam talian, dsb. Oleh kerana AIO menyokong bacaan tak segerak bagi aliran input dan output, ia boleh mengendalikan berbilang permintaan pelanggan pada masa yang sama, dengan berkesan meningkatkan keupayaan pemprosesan serentak pelayan.

    Ringkasan

    Sebagai model IO berprestasi tinggi, berkonkurensi tinggi, Java AIO mempunyai banyak kelebihan, tetapi terdapat juga beberapa kelemahan, seperti sambungan beban kecil, overhed AIO boleh Mengakibatkan kemerosotan prestasi. Oleh itu, dalam aplikasi praktikal, pelbagai faktor perlu ditimbang dan dinilai serta dipilih berdasarkan keperluan sebenar.

    5. Soalan temuduga berkaitan

    1.

    Java IO (Input/Output) ialah operasi input dan output tradisional dalam Java, menggunakan strim bait dan strim aksara untuk penghantaran data.
    Java NIO (Input/Output Baharu) ialah API input dan output baharu yang diperkenalkan dalam Java 1.4, yang memproses data dengan lebih cekap.

    2. Apakah itu menyekat dan tidak menyekat IO?

    Menyekat IO akan menunggu sehingga IO selesai semasa operasi IO, di mana tiada operasi lain boleh dilakukan.
    On-blocking IO (Non-blocking IO) tidak menunggu selama-lamanya apabila melakukan operasi IO, tetapi mengembalikan hasilnya dengan segera Jika IO belum selesai sepenuhnya, anda boleh terus melakukan perkara lain.

    3. Apakah zon penampan? Apakah jenis penimbal yang ada?

    Penimbal ialah tatasusunan yang digunakan untuk menyimpan data Semasa menjalankan operasi IO, penimbal perlu digunakan untuk membaca dan menulis data.
    Penimbal Java dibahagikan kepada penimbal bait (ByteBuffer, CharBuffer, ShortBuffer, dll.) dan penimbal langsung (DirectByteBuffer, DirectCharBuffer, DirectShortBuffer, dsb.).

    4. Apakah itu saluran?

    Saluran ialah objek yang digunakan untuk penghantaran data dalam NIO Ia boleh disambungkan kepada sumber atau nod destinasi untuk membaca dan menulis data.

    5. Apakah itu pemilih?

    Pemilih ialah objek dalam NIO Ia boleh meninjau saluran yang didaftarkan padanya untuk menyemak sama ada mereka mempunyai acara (seperti boleh dibaca, boleh ditulis, dsb.), dengan itu mengelak daripada menyekat IO lengkap.

    6. Apakah perbezaan antara Java IO dan NIO?

    Java IO menghantar data berdasarkan strim, manakala NIO menghantar data berdasarkan penimbal dan saluran.
    Java IO menyekat, manakala NIO boleh berada dalam mod menyekat atau tidak menyekat.
    Java IO menggunakan lebih banyak benang, dan setiap operasi IO memerlukan penciptaan benang, manakala NIO boleh menggunakan satu benang untuk mengendalikan berbilang operasi IO.

    7. Apakah itu FileChannel?

    Saluran fail ialah saluran yang digunakan dalam NIO untuk membaca dan menulis fail Ia menyokong ciri lanjutan seperti akses rawak dan fail dipetakan memori.

    8. Mana satu lebih cepat, Java IO atau NIO?

    Dalam kes sejumlah besar data kecil, Java IO mungkin lebih pantas kerana ia boleh membaca semua data sekaligus melalui penimbal.
    Dalam kes sejumlah besar blok data yang besar, NIO mungkin lebih pantas kerana ia boleh menggunakan teknologi sifar-salinan untuk membaca terus data daripada cakera ke dalam memori, mengurangkan overhed penyalinan data.

    Atas ialah kandungan terperinci Analisis perbandingan input dan output Java IO, NIO dan AIO. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

    Kenyataan:
    Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam