Java NIO快速参考指南
1. 简介
Java NIO(New I/O)提供了一组强大的类和接口,用于高效的I/O操作。本指南将对Java NIO中的核心类和接口进行快速参考,涵盖
java.nio
和
java.nio.channels
包中的重要内容。
2.
java.nio
包
java.nio
包包含了用于
java.nio.channels
和
java.nio.charset
子包中的
Buffer
类。
2.1
Buffer
类
Buffer
是所有其他缓冲区类的基类,包含了所有缓冲区类型通用的方法。以下是
Buffer
类的定义:
public abstract class Buffer {
public final int capacity()
public final Buffer clear()
public final Buffer flip()
public final boolean hasRemaining()
public abstract boolean isReadOnly();
public final int limit()
public final Buffer limit (int newLimit)
public final Buffer mark()
public final int position()
public final Buffer position (int newPosition)
public final int remaining()
public final Buffer reset()
public final Buffer rewind()
}
2.2 异常类
-
BufferOverflowException:当缓冲区的位置等于其限制时,尝试进行简单的相对put()操作,或者批量put()操作会导致位置超过限制时,抛出此异常。
public class BufferOverflowException extends RuntimeException {
public BufferOverflowException()
}
-
BufferUnderflowException:当缓冲区的位置等于其限制时,尝试进行简单的相对get()操作,或者批量get()操作会导致位置超过限制时,抛出此异常。
public class BufferUnderflowException extends RuntimeException {
public BufferUnderflowException()
}
2.3
ByteBuffer
类
ByteBuffer
是所有缓冲区类中最复杂和通用的。只有字节缓冲区可以参与通道上的I/O操作以发送和接收数据。以下是
ByteBuffer
类的部分定义:
public abstract class ByteBuffer extends Buffer implements Comparable {
public static ByteBuffer allocate (int capacity)
public static ByteBuffer allocateDirect (int capacity)
public final byte [] array()
public final int arrayOffset()
public abstract CharBuffer asCharBuffer();
// 其他方法...
}
2.4
ByteOrder
类
ByteOrder
是一个类型安全的枚举,不能直接实例化。有两个公共可访问的
ByteOrder
实例作为静态类字段可见。提供了一个类方法来确定底层操作系统的本地字节顺序,这可能与Java平台默认的不同。
public final class ByteOrder {
public static final ByteOrder BIG_ENDIAN
public static final ByteOrder LITTLE_ENDIAN
public static ByteOrder nativeOrder()
public String toString()
}
2.5 其他缓冲区类
除了上述类,
java.nio
包中还包含了
CharBuffer
、
DoubleBuffer
、
FloatBuffer
、
IntBuffer
、
LongBuffer
、
ShortBuffer
等类,它们分别管理不同类型的数据元素。以下是
CharBuffer
类的部分定义:
public abstract class CharBuffer extends Buffer implements Comparable, CharSequence {
public static CharBuffer allocate (int capacity)
public final char [] array()
public final int arrayOffset()
public abstract CharBuffer asReadOnlyBuffer();
// 其他方法...
}
2.6 异常类
-
InvalidMarkException:当在没有设置标记的缓冲区上调用reset()方法时,抛出此异常。
public class InvalidMarkException extends IllegalStateException {
public InvalidMarkException()
}
-
ReadOnlyBufferException:当在只读缓冲区上调用会修改缓冲区内容的方法(如put()或compact())时,抛出此异常。
public class ReadOnlyBufferException extends UnsupportedOperationException {
public ReadOnlyBufferException()
}
2.7
MappedByteBuffer
类
MappedByteBuffer
是一种特殊类型的
ByteBuffer
,其数据元素是磁盘文件的内容。只能通过调用
FileChannel
对象的
map()
方法来创建
MappedByteBuffer
对象。
public abstract class MappedByteBuffer extends ByteBuffer {
public final MappedByteBuffer force()
public final boolean isLoaded()
public final MappedByteBuffer load()
}
3.
java.nio.channels
包
java.nio.channels
包包含了与通道和选择器相关的类和接口。
3.1 异常类
-
AlreadyConnectedException:当在已经连接的SocketChannel对象上调用connect()方法时,抛出此异常。
public class AlreadyConnectedException extends IllegalStateException {
public AlreadyConnectedException()
}
-
AsynchronousCloseException:当一个线程在通道操作(如read()或write())上被阻塞,而另一个线程关闭了该通道时,抛出此异常。
public class AsynchronousCloseException extends ClosedChannelException {
public AsynchronousCloseException()
}
3.2 接口类
-
ByteChannel:这是一个空的聚合接口,将ReadableByteChannel和WritableByteChannel组合成一个单一的接口,但不定义任何新方法。
public interface ByteChannel extends ReadableByteChannel, WritableByteChannel {
}
-
Channel:是所有其他通道接口的超接口,定义了所有具体通道类通用的方法。
public interface Channel {
public void close() throws java.io.IOException;
public boolean isOpen();
}
3.3
Channels
工具类
Channels
是一个实用类,使通道能够与传统的字节和字符流进行互操作。工厂方法返回包装对象,使通道适应流,反之亦然。返回的通道对象可能不可选择或不可中断。
public final class Channels {
public static ReadableByteChannel newChannel (java.io.InputStream in)
public static WritableByteChannel newChannel (java.io.OutputStream out)
public static java.io.InputStream newInputStream (ReadableByteChannel ch)
public static java.io.OutputStream newOutputStream (WritableByteChannel ch)
public static java.io.Reader newReader (ReadableByteChannel ch, String csName)
public static java.io.Reader newReader (ReadableByteChannel ch, java.nio.charset.CharsetDecoder dec, int minBufferCap)
public static java.io.Writer newWriter (WritableByteChannel ch, String csName)
public static java.io.Writer newWriter (WritableByteChannel ch, java.nio.charset.CharsetEncoder enc, int minBufferCap)
}
3.4 其他异常类
-
CancelledKeyException:当尝试使用已失效的SelectionKey对象时,抛出此异常。
public class CancelledKeyException extends IllegalStateException {
public CancelledKeyException()
}
-
ClosedByInterruptException:当一个线程在通道操作(如read()或write())上被阻塞,而另一个线程中断了该线程时,抛出此异常。作为副作用,该线程正在休眠的通道将被关闭。
public class ClosedByInterruptException extends AsynchronousCloseException {
public ClosedByInterruptException()
}
-
ClosedChannelException:当尝试对已关闭的通道进行操作时,抛出此异常。
public class ClosedChannelException extends java.io.IOException {
public ClosedChannelException()
}
-
ClosedSelectorException:当尝试使用已关闭的Selector时,抛出此异常。
public class ClosedSelectorException extends IllegalStateException {
public ClosedSelectorException()
}
-
ConnectionPendingException:当在非阻塞模式的SocketChannel对象上调用connect()方法,而该对象已经有一个并发连接正在进行时,抛出此异常。
public class ConnectionPendingException extends IllegalStateException {
public ConnectionPendingException()
}
3.5
DatagramChannel
类
DatagramChannel
类提供了从
ByteBuffer
对象发送和接收数据报包的方法。
public abstract class DatagramChannel extends java.nio.channels.spi.AbstractSelectableChannel implements ByteChannel, ScatteringByteChannel, GatheringByteChannel {
public abstract DatagramChannel connect (java.net.SocketAddress remote) throws java.io.IOException;
public abstract DatagramChannel disconnect() throws java.io.IOException;
public abstract boolean isConnected();
public static DatagramChannel open() throws java.io.IOException
public abstract int read (java.nio.ByteBuffer dst) throws java.io.IOException;
public final long read (java.nio.ByteBuffer [] dsts) throws java.io.IOException
public abstract long read (java.nio.ByteBuffer [] dsts, int offset, int length) throws java.io.IOException;
public abstract java.net.SocketAddress receive (java.nio.ByteBuffer dst) throws java.io.IOException;
public abstract int send (java.nio.ByteBuffer src, java.net.SocketAddress target) throws java.io.IOException;
public abstract java.net.DatagramSocket socket();
public final int validOps()
public abstract int write (java.nio.ByteBuffer src) throws java.io.IOException;
public final long write (java.nio.ByteBuffer [] srcs) throws java.io.IOException
public abstract long write (java.nio.ByteBuffer [] srcs, int offset, int length) throws java.io.IOException;
}
3.6
FileChannel
类
FileChannel
类提供了丰富的文件操作。只能通过在
RandomAccessFile
、
FileInputStream
或
FileOutputStream
对象上调用
getChannel()
方法来获取
FileChannel
对象。
public abstract class FileChannel extends java.nio.channels.spi.AbstractInterruptibleChannel implements ByteChannel, GatheringByteChannel, ScatteringByteChannel {
public abstract void force (boolean metaData) throws java.io.IOException;
public final FileLock lock() throws java.io.IOException
public abstract FileLock lock (long position, long size, boolean shared) throws java.io.IOException;
public abstract java.nio.MappedByteBuffer map (FileChannel.MapMode mode, long position, long size) throws java.io.IOException;
public abstract long position() throws java.io.IOException;
public abstract FileChannel position (long newPosition) throws java.io.IOException;
public abstract int read (java.nio.ByteBuffer dst) throws java.io.IOException;
public final long read (java.nio.ByteBuffer [] dsts) throws java.io.IOException
public abstract int read (java.nio.ByteBuffer dst, long position) throws java.io.IOException;
public abstract long read (java.nio.ByteBuffer [] dsts, int offset, int length) throws java.io.IOException;
public abstract long size() throws java.io.IOException;
public abstract long transferFrom (ReadableByteChannel src, long position, long count) throws java.io.IOException;
public abstract long transferTo (long position, long count, WritableByteChannel target) throws java.io.IOException;
public abstract FileChannel truncate (long size) throws java.io.IOException;
public final FileLock tryLock() throws java.io.IOException
public abstract FileLock tryLock (long position, long size, boolean shared) throws java.io.IOException;
public abstract int write (java.nio.ByteBuffer src) throws java.io.IOException;
public final long write (java.nio.ByteBuffer [] srcs) throws java.io.IOException
public abstract int write (java.nio.ByteBuffer src, long position) throws java.io.IOException;
public abstract long write (java.nio.ByteBuffer [] srcs, int offset, int length) throws java.io.IOException;
public static class FileChannel.MapMode {
public static final FileChannel.MapMode PRIVATE
public static final FileChannel.MapMode READ_ONLY
public static final FileChannel.MapMode READ_WRITE
public String toString()
}
}
3.7
FileLock
类
FileLock
类封装了与
FileChannel
对象关联的锁区域。
public abstract class FileLock {
public final FileChannel channel()
public final boolean isShared()
public abstract boolean isValid();
public final boolean overlaps (long position, long size)
public final long position()
public abstract void release() throws java.io.IOException;
public final long size()
public final String toString()
}
总结
本部分介绍了
java.nio
和
java.nio.channels
包中的核心类和接口,包括缓冲区类、通道类、异常类等。这些类和接口为Java中的高效I/O操作提供了强大的支持。通过合理使用这些类和接口,可以实现更高效、更灵活的I/O编程。
流程图
graph TD;
A[java.nio包] --> B[Buffer类];
A --> C[ByteBuffer类];
A --> D[ByteOrder类];
A --> E[其他缓冲区类];
A --> F[异常类];
A --> G[MappedByteBuffer类];
H[java.nio.channels包] --> I[异常类];
H --> J[接口类];
H --> K[Channels工具类];
H --> L[其他异常类];
H --> M[DatagramChannel类];
H --> N[FileChannel类];
H --> O[FileLock类];
表格
| 包名 | 类名 | 描述 |
|---|---|---|
| java.nio | Buffer | 所有缓冲区类的基类 |
| java.nio | ByteBuffer | 最复杂和通用的缓冲区类,可参与I/O操作 |
| java.nio | ByteOrder | 类型安全的枚举,用于确定字节顺序 |
| java.nio.channels | DatagramChannel | 用于发送和接收数据报包 |
| java.nio.channels | FileChannel | 提供丰富的文件操作 |
3.8 各异常类及相关类的关系总结
为了更清晰地理解
java.nio.channels
包中各异常类以及相关类之间的关系,我们可以通过以下表格和流程图进行总结。
| 异常类/相关类 | 父类/接口 | 触发条件 |
|---|---|---|
AlreadyConnectedException
|
IllegalStateException
|
在已连接的
SocketChannel
对象上调用
connect()
方法
|
AsynchronousCloseException
|
ClosedChannelException
| 线程在通道操作被阻塞时,通道被其他线程关闭 |
CancelledKeyException
|
IllegalStateException
|
尝试使用已失效的
SelectionKey
对象
|
ClosedByInterruptException
|
AsynchronousCloseException
| 线程在通道操作被阻塞时,被其他线程中断 |
ClosedChannelException
|
IOException
| 尝试对已关闭的通道进行操作 |
ClosedSelectorException
|
IllegalStateException
|
尝试使用已关闭的
Selector
|
ConnectionPendingException
|
IllegalStateException
|
在非阻塞模式的
SocketChannel
对象上调用
connect()
,且已有并发连接在进行
|
graph TD;
A[IOException] --> B[ClosedChannelException];
B --> C[AsynchronousCloseException];
C --> D[ClosedByInterruptException];
E[IllegalStateException] --> F[AlreadyConnectedException];
E --> G[CancelledKeyException];
E --> H[ClosedSelectorException];
E --> I[ConnectionPendingException];
J[Channel] --> K[SocketChannel];
K --> F;
K --> I;
L[SelectionKey] --> G;
M[Selector] --> H;
N[AbstractSelectableChannel] --> O[DatagramChannel];
P[AbstractInterruptibleChannel] --> Q[FileChannel];
4. 操作示例
4.1
ByteBuffer
的使用示例
以下是一个简单的
ByteBuffer
使用示例,展示了如何分配缓冲区、写入数据和读取数据。
import java.nio.ByteBuffer;
public class ByteBufferExample {
public static void main(String[] args) {
// 分配一个容量为10的ByteBuffer
ByteBuffer buffer = ByteBuffer.allocate(10);
// 写入数据
buffer.put((byte) 1);
buffer.put((byte) 2);
buffer.put((byte) 3);
// 切换到读模式
buffer.flip();
// 读取数据
while (buffer.hasRemaining()) {
System.out.println(buffer.get());
}
}
}
4.2
FileChannel
的使用示例
以下示例展示了如何使用
FileChannel
读取文件内容。
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class FileChannelExample {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("test.txt");
FileChannel channel = fis.getChannel()) {
// 分配一个容量为1024的ByteBuffer
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);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
5. 总结与展望
Java NIO提供的类和接口为高效的I/O操作提供了强大的支持。
java.nio
包中的缓冲区类可以帮助我们更好地管理数据,而
java.nio.channels
包中的通道类和选择器类则为非阻塞I/O操作提供了可能。
通过合理使用这些类和接口,我们可以实现更高效、更灵活的I/O编程。例如,在网络编程中,可以使用
DatagramChannel
和
SocketChannel
进行数据的发送和接收;在文件操作中,可以使用
FileChannel
进行文件的读写和锁定。
未来,随着技术的不断发展,Java NIO可能会进一步优化和扩展,以满足更多的应用场景需求。例如,可能会提供更高效的缓冲区管理机制,或者支持更多类型的通道操作。开发者可以持续关注Java NIO的发展,以便在实际项目中更好地应用这些技术。
流程图
graph TD;
A[操作示例] --> B[ByteBuffer示例];
A --> C[FileChannel示例];
B --> D[分配缓冲区];
B --> E[写入数据];
B --> F[切换到读模式];
B --> G[读取数据];
C --> H[创建FileInputStream];
H --> I[获取FileChannel];
I --> J[分配ByteBuffer];
J --> K[读取数据到缓冲区];
K --> L[切换到读模式];
L --> M[处理数据];
M --> N[清空缓冲区];
N --> K;
表格
| 操作示例 | 步骤 | 代码片段 |
|---|---|---|
| ByteBuffer示例 | 分配缓冲区 |
ByteBuffer buffer = ByteBuffer.allocate(10);
|
| ByteBuffer示例 | 写入数据 |
buffer.put((byte) 1);
|
| ByteBuffer示例 | 切换到读模式 |
buffer.flip();
|
| ByteBuffer示例 | 读取数据 |
buffer.get();
|
| FileChannel示例 | 创建FileInputStream |
FileInputStream fis = new FileInputStream("test.txt");
|
| FileChannel示例 | 获取FileChannel |
FileChannel channel = fis.getChannel();
|
| FileChannel示例 | 分配ByteBuffer |
ByteBuffer buffer = ByteBuffer.allocate(1024);
|
| FileChannel示例 | 读取数据到缓冲区 |
int bytesRead = channel.read(buffer);
|
| FileChannel示例 | 切换到读模式 |
buffer.flip();
|
| FileChannel示例 | 处理数据 |
System.out.print((char) buffer.get());
|
| FileChannel示例 | 清空缓冲区 |
buffer.clear();
|
超级会员免费看
1242

被折叠的 条评论
为什么被折叠?



