Java的NIO提供了非阻塞I/O机制的包

Java的NIO(New I/O)是一种提供了替代性、非阻塞I/O机制的包。它的引入主要是为了解决传统I/O机制在处理大量连接或大数据量时所带来的性能瓶颈和可扩展性问题。下面详细介绍NIO的一些关键概念和特性:

1.通道(Channels):
NIO中引入了通道的概念,它是连接程序与文件、套接字等I/O资源的虚拟管道。通道可以用于读取和写入数据,并且通道的实现可以支持非阻塞模式,使得一个线程可以管理多个通道。
2.缓冲区(Buffers):
在NIO中,数据的读取和写入都是通过缓冲区进行的。缓冲区是一个对象,它包含了一定数量的数据,并提供了读写这些数据的方法。通过缓冲区,可以减少对底层系统的直接访问次数,从而提高了性能。
3.选择器(Selectors):
选择器是NIO提供的一种高效的多路复用机制。它可以让一个单独的线程管理多个通道的I/O操作,从而降低了线程开销。选择器会监视多个通道的事件,例如读就绪、写就绪等,并且只会在有事件发生时才唤醒线程。
4.非阻塞I/O(Non-blocking I/O):
NIO的关键特性之一是非阻塞I/O。在传统的I/O模型中,当一个线程在一个通道上进行读取或写入操作时,如果数据还没有准备好,线程会被阻塞,直到数据准备好为止。而在NIO中,可以通过设置通道为非阻塞模式,使得当数据还没有准备好时,不会阻塞线程,而是立即返回,这样线程可以继续处理其他通道。
5.文件I/O和网络I/O的统一模型:
NIO提供了一种统一的模型来处理文件I/O和网络I/O。通道、缓冲区和选择器这些核心概念在处理文件和网络时都可以使用,使得开发人员能够更方便地编写可重用的代码。

总的来说,Java的NIO提供了一种更为灵活和高效的I/O机制,特别适用于需要处理大量连接或大数据量的应用场景,例如网络服务器、消息传输系统等。通过NIO,开发人员能够更好地利用系统资源,提高应用程序的性能和可伸缩性。

--------

Java的NIO(New I/O)提供了一组类和接口来支持非阻塞I/O操作。下面是一些核心类及其方法的详细介绍:

通道相关类(Channels):
java.nio.channels.Channel:通道的基本接口,定义了通道的基本操作,如打开、关闭和判断是否打开等。常见的实现类有:
FileChannel:用于文件I/O操作的通道。
SocketChannel:用于TCP网络套接字的通道。
ServerSocketChannel:用于监听TCP连接请求的通道。
DatagramChannel:用于UDP数据报套接字的通道。
java.nio.channels.SelectableChannel:可选择通道的基本接口,扩展了Channel接口,提供了支持选择器的功能。

缓冲区相关类(Buffers):
java.nio.Buffer:缓冲区的基本抽象类,定义了缓冲区的基本操作,如读取、写入、清空、翻转等。
ByteBuffer:字节缓冲区,用于读取和写入字节数据。
CharBuffer:字符缓冲区,用于读取和写入字符数据。

ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer:分别用于读取和写入不同基本数据类型的缓冲区。

选择器相关类(Selectors):
java.nio.channels.Selector:选择器类,用于管理多个通道的事件。
Selector.open():静态方法,用于打开一个选择器。
Selector.select():阻塞方法,用于等待通道上的事件发生。
Selector.selectedKeys():返回一个包含已选择键的集合,这些键表示通道上已经准备好的I/O操作。

其他核心类:
java.nio.file.Path:路径类,用于表示文件系统中的路径。
java.nio.file.Files:文件操作类,提供了一系列静态方法来操作文件,如复制、移动、删除等。

常用方法和操作:
通道相关方法:
Channel.open():打开一个通道。
Channel.close():关闭通道。
Channel.read():从通道读取数据到缓冲区。
Channel.write():将缓冲区中的数据写入通道。
缓冲区相关方法:
Buffer.allocate(int capacity):分配一个新的缓冲区。
Buffer.clear():清空缓冲区,使其准备好写入数据。
Buffer.flip():翻转缓冲区,使其准备好读取数据。
Buffer.put():向缓冲区中写入数据。
Buffer.get():从缓冲区中读取数据。
选择器相关方法:
Selector.open():打开一个选择器。
Selector.select():阻塞方法,等待通道上的事件发生。
Selector.selectedKeys():获取已选择的键集合。
SelectableChannel.register(Selector sel, int ops):注册通道到选择器,并指定感兴趣的事件类型。
通过这些类和方法,Java的NIO提供了强大的工具来实现高效的非阻塞I/O操作,可以应用于各种场景,包括网络编程、文件操作等。

-----------

// 这段Java程序利用了Java NIO(New I/O)库进行文件操作,主要涉及了ByteBuffer、FileChannel等类。让我逐步解释每一行代码:
// 1. `RandomAccessFile file = new RandomAccessFile("example.txt", "rw");`:这行代码打开名为"example.txt"的文件,使用读写模式("rw"表示读写)创建一个RandomAccessFile对象。
// 2. `FileChannel channel = file.getChannel();`:通过RandomAccessFile对象获取文件的通道,以便后续进行读写操作。
// 3. `ByteBuffer byteBuffer = ByteBuffer.allocate(1024);`:创建一个大小为1024字节的ByteBuffer对象,用于缓存从文件中读取的数据。
// 4. `int bytesRead = channel.read(byteBuffer);`:从文件通道中读取数据到ByteBuffer中,并返回读取的字节数。
// 5. `while (bytesRead != -1) { ... }`:通过一个while循环来读取文件,条件是文件中还有未读取的数据。
// 6. `byteBuffer.flip();`:切换ByteBuffer为读取模式,准备从缓冲区中读取数据。这里是为了读取之前放入ByteBuffer的数据。
// 7. `CharBuffer charBuffer = StandardCharsets.UTF_8.decode(byteBuffer);`:将ByteBuffer中的字节数据按照UTF-8编码解码为字符,存储到CharBuffer中。
// 8. `System.out.print(charBuffer);`:将字符缓冲区中的内容打印到控制台。
// 9. `byteBuffer.clear();`:清空ByteBuffer,准备下一次读取。
// 10. `bytesRead = channel.read(byteBuffer);`:继续从文件通道中读取数据到ByteBuffer中,并更新bytesRead以判断是否已经读取到文件末尾。
// 11. `channel.close();`和`file.close();`:关闭文件通道和RandomAccessFile对象,释放资源。
// 总体而言,这段程序通过NIO库实现了从文件中读取数据并输出到控制台的功能。

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.channels.FileChannel;

public class nioFileOperationWithByteBuffer {
    public static void main(String[] args) {
        try {
            // 打开文件
            RandomAccessFile file = new RandomAccessFile("example.txt", "rw");
            FileChannel channel = file.getChannel();

            // 创建一个ByteBuffer
            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

            // 从文件中读取数据到缓冲区
            int bytesRead = channel.read(byteBuffer);
            while (bytesRead != -1) {
                // 切换为读取模式
                byteBuffer.flip();

                // 将字节转换为字符
                CharBuffer charBuffer = StandardCharsets.UTF_8.decode(byteBuffer);

                // 打印字符
                System.out.print(charBuffer);

                // 清空缓冲区,准备下一次读取
                byteBuffer.clear();
                bytesRead = channel.read(byteBuffer);
            }

            // 关闭通道和文件
            channel.close();
            file.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
// 这段Java程序利用了Java NIO(New I/O)库进行文件操作,主要涉及了ByteBuffer、FileChannel等类。让我逐步解释每一行代码:
// 1. `RandomAccessFile file = new RandomAccessFile("example.txt", "rw");`:这行代码打开名为"example.txt"的文件,使用读写模式("rw"表示读写)创建一个RandomAccessFile对象。
// 2. `FileChannel channel = file.getChannel();`:通过RandomAccessFile对象获取文件的通道,以便后续进行读写操作。
// 3. `ByteBuffer byteBuffer = ByteBuffer.allocate(1024);`:创建一个大小为1024字节的ByteBuffer对象,用于缓存从文件中读取的数据。
// 4. `int bytesRead = channel.read(byteBuffer);`:从文件通道中读取数据到ByteBuffer中,并返回读取的字节数。
// 5. `while (bytesRead != -1) { ... }`:通过一个while循环来读取文件,条件是文件中还有未读取的数据。
// 6. `byteBuffer.flip();`:切换ByteBuffer为读取模式,准备从缓冲区中读取数据。这里是为了读取之前放入ByteBuffer的数据。
// 7. `CharBuffer charBuffer = StandardCharsets.UTF_8.decode(byteBuffer);`:将ByteBuffer中的字节数据按照UTF-8编码解码为字符,存储到CharBuffer中。
// 8. `System.out.print(charBuffer);`:将字符缓冲区中的内容打印到控制台。
// 9. `byteBuffer.clear();`:清空ByteBuffer,准备下一次读取。
// 10. `bytesRead = channel.read(byteBuffer);`:继续从文件通道中读取数据到ByteBuffer中,并更新bytesRead以判断是否已经读取到文件末尾。
// 11. `channel.close();`和`file.close();`:关闭文件通道和RandomAccessFile对象,释放资源。
// 总体而言,这段程序通过NIO库实现了从文件中读取数据并输出到控制台的功能。


// `RandomAccessFile` 类是 Java 提供的一个用于文件操作的工具类,可以在文件中随机访问数据。它既可以读取文件的内容,也可以向文件中写入数据,并且可以随机定位文件指针到文件的任意位置进行读写操作。
// 下面是 `RandomAccessFile` 类的一些主要方法和用法:
// 1. **构造方法**:
//    - `RandomAccessFile(String name, String mode)`:根据指定的文件名和模式("r":只读,"rw":读写)创建一个 `RandomAccessFile` 对象。
// 2. **读取操作**:
//    - `int read()`:从文件中读取一个字节的数据,并返回读取到的字节数据(返回值范围在 0 到 255 之间)。
//    - `int read(byte[] b)`:从文件中读取最多 `b.length` 个字节的数据,并将其存储到字节数组 `b` 中,返回实际读取的字节数。
//    - `long getFilePointer()`:返回当前文件指针的位置,即从文件开头到当前位置的字节数。
// 3. **写入操作**:
//    - `void write(int b)`:向文件中写入一个字节的数据。
//    - `void write(byte[] b)`:将字节数组 `b` 中的数据写入到文件中。
//    - `void writeBytes(String s)`:将字符串 `s` 中的字节写入到文件中。
// 4. **定位操作**:
//    - `void seek(long pos)`:将文件指针定位到指定的位置 `pos`。
// 5. **关闭文件**:
//    - `void close()`:关闭文件流,释放资源。
// `RandomAccessFile` 类提供了比较底层的文件操作方法,可以对文件进行灵活的读写操作,但需要注意的是,在进行文件指针的定位时,需要小心确保定位的位置在文件的有效范围内。

-------------

// 代码示例中,我们使用了以下文件和字符流文件流类:
// RandomAccessFile:RandomAccessFile 类提供了对文件的随机读写访问。它既可以用于读取数据,也可以用于写入数据。与传统的输入输出流不同,RandomAccessFile 允许我们通过设置文件指针来跳转到文件的任意位置,并在该位置进行读取或写入操作。
// FileChannel:FileChannel 是 NIO(New I/O)包提供的通道类,用于高效地进行文件读写操作。通道提供了更灵活和高性能的方式来操作文件,支持异步读写、文件锁定等功能。通过 FileChannel 可以直接操作文件的内容,读取或写入字节数据。
// ByteBuffer:ByteBuffer 是 NIO 包中的一个字节缓冲区类,用于存储原始的字节数据。在文件操作中,我们通常会先将文件内容读取到 ByteBuffer 中,然后再进行相应的处理。
// CharBuffer:
CharBuffer 是 NIO 包中的一个字符缓冲区类,用于存储字符数据。在处理文本文件时,我们通常会将字节数据解码为字符数据,并存储到 CharBuffer 中。
// Charset:Charset 类表示字符编码集,用于处理字符数据和字节数据之间的转换。在文件操作中,我们经常需要指定正确的字符编码集来解码文件内容,以确保正确地读取和显示文本数据。
// 这些文件和字符流文件流类提供了多种功能和方法,使得我们能够有效地进行文件操作、数据读写和字符编解码。通过结合使用这些类,我们可以实现各种文件处理需求,并灵活地控制文件内容的读取和写入过程。

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

public class nioFileOperationWithCharBuffer {
    public static void main(String[] args) {
        try {
            // 打开一个随机访问文件以只读模式打开
            RandomAccessFile file = new RandomAccessFile("example.txt", "r");
            FileChannel channel = file.getChannel(); // 获取文件通道

            channel.position(0); // 移动文件指针到文件开头

            ByteBuffer byteBuffer = ByteBuffer.allocate(1024); // 创建一个字节缓冲区
            CharBuffer charBuffer = CharBuffer.allocate(1024); // 创建一个字符缓冲区

            Charset charset = StandardCharsets.UTF_8; // 指定UTF-8字符集

            int bytesRead;
            while ((bytesRead = channel.read(byteBuffer)) != -1) { // 从文件通道中读取数据到字节缓冲区
                byteBuffer.flip(); // 切换为读模式

                // 使用指定字符集将字节缓冲区的数据解码到字符缓冲区
                charset.newDecoder().decode(byteBuffer, charBuffer, false);

                charBuffer.flip(); // 准备从字符缓冲区读取数据

                // 逐个字符地从字符缓冲区中读取数据并输出到控制台
                while (charBuffer.hasRemaining()) {
                    System.out.print(charBuffer.get());
                }

                byteBuffer.clear(); // 清空字节缓冲区,准备下一次读取
                charBuffer.clear(); // 清空字符缓冲区,以便下一次解码

            }

            channel.close(); // 关闭文件通道
            file.close(); // 关闭文件
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
// 关键内容解读:

// ByteBuffer:用于存储从文件中读取的原始字节数据。
// CharBuffer:用于存储通过解码后的字符数据。
// Charset:表示字符编码集,用于将字节数据解码为字符数据。
// StandardCharsets.UTF_8:Java标准字符集之一,表示UTF-8编码。
// channel.read(byteBuffer):从文件通道中读取数据,并将其存储到ByteBuffer中。
// charset.newDecoder().decode(byteBuffer, charBuffer, false):使用指定字符集解码ByteBuffer中的字节数据,并将结果存储到CharBuffer中。
// byteBuffer.flip() 和 charBuffer.flip():切换缓冲区为读取模式。
// charBuffer.hasRemaining() 和 charBuffer.get():循环遍历字符缓冲区,逐个字符读取并输出到控制台。
// byteBuffer.clear() 和 charBuffer.clear():清空缓冲区,以便进行下一轮读取或解码操作。


// 在上面的代码示例中,我们使用了以下文件和字符流文件流类:
// RandomAccessFile:RandomAccessFile 类提供了对文件的随机读写访问。它既可以用于读取数据,也可以用于写入数据。与传统的输入输出流不同,RandomAccessFile 允许我们通过设置文件指针来跳转到文件的任意位置,并在该位置进行读取或写入操作。
// FileChannel:FileChannel 是 NIO(New I/O)包提供的通道类,用于高效地进行文件读写操作。通道提供了更灵活和高性能的方式来操作文件,支持异步读写、文件锁定等功能。通过 FileChannel 可以直接操作文件的内容,读取或写入字节数据。
// ByteBuffer:ByteBuffer 是 NIO 包中的一个字节缓冲区类,用于存储原始的字节数据。在文件操作中,我们通常会先将文件内容读取到 ByteBuffer 中,然后再进行相应的处理。
// CharBuffer: CharBuffer 是 NIO 包中的一个字符缓冲区类,用于存储字符数据。在处理文本文件时,我们通常会将字节数据解码为字符数据,并存储到 CharBuffer 中。
// Charset:Charset 类表示字符编码集,用于处理字符数据和字节数据之间的转换。在文件操作中,我们经常需要指定正确的字符编码集来解码文件内容,以确保正确地读取和显示文本数据。
// 这些文件和字符流文件流类提供了多种功能和方法,使得我们能够有效地进行文件操作、数据读写和字符编解码。通过结合使用这些类,我们可以实现各种文件处理需求,并灵活地控制文件内容的读取和写入过程。

---

// 这段示例代码涉及了java.io中的字节流和字符流,以及文件输入输出类。让我详细介绍一下涉及的各个对象:

// 1. **字节流和字符流**:
//    - `FileInputStream`:字节流输入,用于从文件中读取字节数据。
//    - `FileOutputStream`:字节流输出,用于将字节数据写入文件中。
//    - `InputStreamReader`:字符流输入,将字节流转换为字符流。它接收一个字节输入流,并将其转换为字符流。通常与`FileInputStream`一起使用。
//    - `OutputStreamWriter`:字符流输出,将字符流转换为字节流。它接收一个字节输出流,并将其转换为字符流。通常与`FileOutputStream`一起使用。

// 2. **缓冲字符流**:
//    - `BufferedReader`:缓冲字符输入流,用于提高读取文件的效率。它接收一个字符输入流,并提供了`readLine()`方法来逐行读取文件内容。
//    - `BufferedWriter`:缓冲字符输出流,用于提高向文件写入数据的效率。它接收一个字符输出流,并提供了`write()`方法来写入字符串到文件中,以及`newLine()`方法来写入换行符。

// 这些流类的组合使得文件的读取和写入变得更加高效和灵活。字符流与字节流的转换使得处理文本数据更为方便,而缓冲流则减少了IO操作的次数,从而提升了性能。

import java.io.*;

public class FileIOExample {
    public static void main(String[] args) {
        try {
            // 文件输入示例
            FileInputStream fis = new FileInputStream("example.txt"); // 创建文件输入流对象,读取名为"example.txt"的文件
            InputStreamReader isr = new InputStreamReader(fis); // 创建字符流输入对象,将字节流转换为字符流
            BufferedReader br = new BufferedReader(isr); // 创建缓冲字符输入流对象,提高读取效率

            String line;
            while ((line = br.readLine()) != null) { // 逐行读取文件内容,直到文件结束
                System.out.println(line); // 输出每行内容到控制台
            }

            br.close(); // 关闭输入流

            // 文件输出示例
            FileOutputStream fos = new FileOutputStream("outputexample.txt"); // 创建文件输出流对象,写入到名为"outputexample.txt"的文件
            OutputStreamWriter osw = new OutputStreamWriter(fos); // 创建字符流输出对象,将字节流转换为字符流
            BufferedWriter bw = new BufferedWriter(osw); // 创建缓冲字符输出流对象,提高写入效率

            bw.write("Hello, world!"); // 写入字符串到文件
            bw.newLine(); // 写入换行符
            bw.write("这是中文字符。"); // 再次写入字符串到文件
            
            bw.close(); // 关闭输出流
        } catch (IOException e) {
            e.printStackTrace(); // 打印异常信息
        }
    }
}
// 这段示例代码涉及了Java中的字节流和字符流,以及文件输入输出类。让我详细介绍一下涉及的各个对象:

// 1. **字节流和字符流**:
//    - `FileInputStream`:字节流输入,用于从文件中读取字节数据。
//    - `FileOutputStream`:字节流输出,用于将字节数据写入文件中。
//    - `InputStreamReader`:字符流输入,将字节流转换为字符流。它接收一个字节输入流,并将其转换为字符流。通常与`FileInputStream`一起使用。
//    - `OutputStreamWriter`:字符流输出,将字符流转换为字节流。它接收一个字节输出流,并将其转换为字符流。通常与`FileOutputStream`一起使用。

// 2. **缓冲字符流**:
//    - `BufferedReader`:缓冲字符输入流,用于提高读取文件的效率。它接收一个字符输入流,并提供了`readLine()`方法来逐行读取文件内容。
//    - `BufferedWriter`:缓冲字符输出流,用于提高向文件写入数据的效率。它接收一个字符输出流,并提供了`write()`方法来写入字符串到文件中,以及`newLine()`方法来写入换行符。

// 这些流类的组合使得文件的读取和写入变得更加高效和灵活。字符流与字节流的转换使得处理文本数据更为方便,而缓冲流则减少了IO操作的次数,从而提升了性能。

  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值