理解java.nio包中的通道

理解java.nio包中的通道,java,io,buffer,nio,Java,Io,Buffer,Nio,对于直接映射的缓冲区,它们始终位于jvm堆之外。另一方面,通道似乎也存在于IO操作中。我只是想知道直接映射缓冲区的对应通道是否也位于jvm堆之外 另外,另一个问题来自内存运行效率方面存在通道的必要性。我明白 通道表示与实体(如硬件设备)的开放连接 然而,在通过直接映射缓冲区写入文件的情况下,内容是否被写入两次?内容首先写入缓冲区,然后写入通道。与“直接”写入IO设备相比,这会是低效率的吗 我只是想知道直接映射缓冲区的对应通道是否也位于jvm堆之外 这个问题没有意义。通道不是内存,它是操作系统的接

对于直接映射的缓冲区,它们始终位于jvm堆之外。另一方面,通道似乎也存在于IO操作中。我只是想知道直接映射缓冲区的对应通道是否也位于jvm堆之外

另外,另一个问题来自内存运行效率方面存在通道的必要性。我明白

通道表示与实体(如硬件设备)的开放连接

然而,在通过直接映射缓冲区写入文件的情况下,内容是否被写入两次?内容首先写入缓冲区,然后写入通道。与“直接”写入IO设备相比,这会是低效率的吗

我只是想知道直接映射缓冲区的对应通道是否也位于jvm堆之外

这个问题没有意义。通道不是内存,它是操作系统的接口

在通过直接映射缓冲区写入文件的情况下,内容是否被写入两次?内容首先写入缓冲区,然后写入通道。与“直接”写入IO设备相比,这会是低效率的吗

否。
MappedByteBuffer
独立于它来自的频道。例如,当通道关闭时,它不会关闭


您是否正在寻找直接字节缓冲区?它们确实存在,您可以通过通道向它们写入,但通过它们的I/O只发生一次,而不是两次。

我想我找到了答案

直接映射缓冲区首先写入缓冲区,这是非IO操作。更新文件的实写IO操作随后发生。两次写入的原因是因为我们有DMA,所以我们不希望所有IO操作都按时间进行。一次完成所有IO操作更高效


通过JNI获取起始地址不是访问该内存块的正确地址。相反,数据的地址是一个隐藏在java.nio.buffer中的字段。获取此字段的一种方法是通过sun.misc.Unsafe将字段公开。

谢谢您的回答。假设我正在写一个文件。这是否意味着它首先对缓冲区进行非IO写入,然后通过通道将IO写入实际文件?对于缓冲区本身,如果我从JNI获得其起始地址,并知道内存中的对象布局(以了解实际内容的偏移量)。是否可以保证我可以从起始地址+偏移量获取真正的文件内容?@jer_-yin您似乎从未编写过任何NIO代码。您将数据放入缓冲区,然后调用
channel.write(buffer)。
对于读取,您调用
channel.read(buffer)
,然后从缓冲区获取数据。我问这个问题也不是为了编写NIO代码。