java nio FileChannel源码分析

本文详细分析了Java NIO中的FileChannel,包括其构造函数、NO_ATTRIBUTES字段、多种读写方法,如open、read、write等。此外,还探讨了FileChannel的position、size、truncate、force、transferTo、transferFrom等操作,以及内部类MapMode及其map、lock和tryLock方法。
摘要由CSDN通过智能技术生成

目录

简介

构造函数,字段NO_ATTRIBUTES,方法2个open,3个read,3个write

方法2个position,size,truncate,force,transferTo,transferFrom,read,write

内部类MapMode

方法map,2个lock,2个tryLock


简介


package java.nio.channels;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.spi.AbstractInterruptibleChannel;
import java.nio.file.*;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.spi.*;
import java.util.Set;
import java.util.HashSet;
import java.util.Collections;

/**
 * 用于读取、写入、映射和操作文件的通道。
 *
 * <p> 文件通道是连接到文件的可查找字节通道。
 * 它在文件中有一个当前位置,可以查询和修改。
 * 文件本身包含一个可变长度的字节序列,这些字节可以读写,并且可以查询其当前大小。
 * 当写入的字节超过当前大小时,文件的大小会增加;
 * 当文件被截断时,文件的大小会减小。
 * 该文件还可能有一些相关的元数据,如访问权限、内容类型和上次修改时间;
 * 此类不定义元数据访问的方法。
 *
 * <p> 除了类似的字节通道的读、写和关闭操作外,此类还定义了以下特定于文件的操作:</p>
 *
 * <ul>
 *
 *   <li><p> 可以在文件的绝对位置以不影响信道当前位置的方式
 *   读取read(ByteBuffer, long)或写入write(ByteBuffer, long)字节。</p></li>
 *
 *   <li><p> 文件的一个区域可以直接映射到内存中;
 *   对于大文件,这通常比调用通常的读或写方法更有效。
 *   </p></li>
 *
 *   <li><p> 对文件所做的更新可以强制到底层存储设备,以确保在系统崩溃时数据不会丢失。</p></li>
 *
 *   <li><p> 字节可以从一个文件传输到另一个通道,
 *   并且可以通过许多操作系统优化的方式,直接传输到文件系统缓存或直接从文件系统缓存传输。
 *   </p></li>
 *
 *   <li><p> 文件的一个区域可能被锁定,不允许其他程序访问。  </p></li>
 *
 * </ul>
 *
 * <p> 多个并发线程可以安全地使用文件通道。
 * close方法可以在任何时候调用,正如Channel接口指定的那样。
 * 在任何给定的时间内,只有一个涉及通道位置或可以更改其文件大小的操作正在进行;
 * 尝试启动第二个此类操作,而正在进行的第一个操作,第二个操作将被阻止,直到第一个操作完成。
 * 其他操作,特别是那些采取明确position的操作,可能同时进行;
 * 它们是否真的这样做取决于底层实现,因此未作说明。
 *
 * <p> 此类实例提供的文件视图被保证与同一程序中其他实例提供的同一文件的其他视图一致。
 * 但是,由于底层操作系统执行的缓存和网络文件系统协议引起的延迟,
 * 此类实例提供的视图可能与其他并发运行的程序所看到的视图一致,也可能不一致。
 * 不管这些程序是用什么语言编写的,也不管它们是在同一台机器上运行还是在其他机器上运行,这都是正确的。
 * 任何此类不一致的确切性质都是系统依赖性的,因此未指定。
 *
 * <p> 文件通道是通过调用这个类定义的一个open方法来创建的。
 * 还可以通过调用该对象的getChannel方法从现有的FileInputStream、
 * FileOutputStream或RandomAccessFile对象获取文件通道,该方法返回连接到同一基础文件的文件通道。
 * 如果文件通道是从现有的流或随机访问文件获得的,那么文件通道的状态与getChannel方法返回通道的对象的状态密切相关。
 * 改变通道的位置,无论是显式的还是读写字节的,都会改变原始对象的文件位置,反之亦然。
 * 通过文件通道更改文件的长度将更改通过原始对象看到的长度,反之亦然。
 * 通过写入字节来更改文件的内容将更改原始对象看到的内容,反之亦然。
 *
 * <a name="open-mode"></a> <p> 
 * 在不同的时候,这个类指定需要一个“为读取打开”、“为写入打开”或“为读写打开”的实例。
 * 通过java.io.FileInputStream的getChannel方法获得的通道,可以进行读取。
 * 通过java.io.FileOutputStream的getChannel方法获得的信道,可以进行写入。
 * 最后,通过java.io.RandomAccessFile的getChannel方法获得的通道,
 * 如果实例创建模式为“r”,可以进行读取,
 * 如果实例创建模式为“rw”,可以进行读取和写入,。
 *
 * <a name="append-mode"></a><p> 为写入而打开的文件通道可能处于追加模式,
 * 例如,如果它是从通过调用FileOutputStream(file,boolean)构造函数并为第二个参数传递true创建的FileOutputStream中获得的。
 * 在这种模式下,每次相对写操作的调用首先将位置推进到文件的末尾,然后写入所请求的数据。
 * 位置的提升和数据的写入是否在单个原子操作中完成是系统依赖的,因此未指定。
 *
 * @see java.io.FileInputStream#getChannel()
 * @see java.io.FileOutputStream#getChannel()
 * @see java.io.RandomAccessFile#getChannel()
 *
 * @author Mark Reinhold
 * @author Mike McCloskey
 * @author JSR-51 Expert Group
 * @since 1.4
 */

public abstract class FileChannel
    extends AbstractInterruptibleChannel
    implements SeekableByteChannel, GatheringByteChannel, ScatteringByteChannel

构造函数,字段NO_ATTRIBUTES,方法2个open,3个read,3个write


    /**
     * Initializes a new instance of this class.
     */
    protected FileChannel() { }

    /**
     * 打开或创建一个文件,返回访问该文件的文件通道。
     *
     * <p> options参数决定如何打开文件。
     * StandardOpenOption.READ和WRITE选项决定是否应该打开文件进行读写。
     * 如果数组中不包含任何选项(或APPEND选项),则打开文件进行读取。
     * 默认情况下,读取或写入从文件的开头开始。
     *
     * <p> 除了读和写之外,可能还会出现以下选项:
     *
     * <table border=1 cellpadding=5 summary="">
     * <tr> <th>Option</th> <th>Description</th> </tr>
     * <tr>
     *   <td> {@link StandardOpenOption#APPEND APPEND} </td>
     *   <td> 如果存在此选项,则打开文件进行写操作,每次调用通道的write方法都会先将该位置移到文件的末尾,然后写入需要的数据。
     *     位置的提升和数据的写入是否在单个原子操作中完成是系统相关的,因此未指定。
     *     此选项不能与READ或TRUNCATE_EXISTING选项联合使用。</td>
     * </tr>
     * <tr>
     *   <td> {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING} </td>
     *   <td> 如果存在此选项,则现有文件将被截断为0字节的大小。
     *   当只打开文件供阅读时,此选项将被忽略。</td>
     * </tr>
     * <tr>
     *   <td> {@link StandardOpenOption#CREATE_NEW CREATE_NEW} </td>
     *   <td> 如果存在此选项,则创建一个新文件,如果文件已经存在则失败。
     *   当创建一个文件时,检查该文件是否存在,如果该文件不存在,则创建该文件,
     *   文件是否存在的检查和文件不存在时的创建相对于其他文件系统操作来说是原子的。
     *   当只打开文件供阅读时,此选项将被忽略。</td>
     * </tr>
     * <tr>
     *   <td > {@link StandardOpenOption#CREATE CREATE} </td>
     *   <td> 如果存在此选项,则打开现有文件(如果存在),否则创建一个新文件。
     *   当创建一个文件时,文件是否存在的检查和文件不存在时的创建相对于其他文件系统操作来说是原子的。
     *   如果还存在CREATE_NEW选项,或者文件只打开用于读取,则忽略该选项。</td>
     * </tr>
     * <tr>
     *   <td > {@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} </td>
     *   <td> 当此选项存在时,实现将尽最大努力,在close方法关闭时,删除文件。
     *   如果close方法没有被调用,那么当Java虚拟机终止时,将尽力删除文件。</td>
     * </tr>
     * <tr>
     *   <td>{@link StandardOpenOption#SPARSE SPARSE} </td>
     *   <td> 当创建一个新文件时,此选项是一个提示,新文件将是稀少的。
     *   当不创建新文件时将忽略此选项。</td>
     * </tr>
     * <tr>
     *   <td> {@link StandardOpenOption#SYNC SYNC} </td>
     *   <td> 要求对文件内容或元数据的每次更新都同步地写入底层存储设备。
     *   (请参阅同步I/O文件完整性)。</td>
     * </tr>
     * <tr>
     *   <td> {@link StandardOpenOption#DSYNC DSYNC} </td>
     *   <td> 要求对文件内容的每次更新都同步地写入底层存储设备。
     *   (请参阅同步I/O文件完整性)。</td>
     * </tr>
     * </table>
     *
     * <p> 实现还可能支持其他选项。
     *
     * <p>  attrs参数是一个可选的FileAttribute数组,FileAttribute是在创建文件时自动设置的。
     *
     * <p> 通过调用创建Path的提供程序FileSystemProvider的newFileChannel方法来创建新通道。
     *
     * @param   path
     *          The path of the file to open or create
     * @param   options
     *          Options specifying how the file is opened
     * @param   attrs
     *          An optional list of file attributes to set atomically when
     *          creating the file
     *
     * @return  A new file channel
     *
     * @throws  IllegalArgumentException
     *          If the set contains an invalid combination of options
     * @throws  UnsupportedOperationException
     *          If the {@code path} is associated with a 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java NIO(New IO)是Java 1.4版本提供的一种新的IO API,它提供了与传统IO API不同的IO处理方式,包括了通道(channel)和缓冲区(buffer)的概念。Java NIO的目标是提供比传统IO更快、更高效的IO操作方式。 Java NIO源码解析需要深入了解Java NIO的核心概念,主要包括以下几个部分: 1. 缓冲区(Buffer):Java NIO中的缓冲区是一个对象,它包含了一定数量的数据元素,并且提供了对这些数据元素的基本操作方法。Java NIO中的所有数据都是通过缓冲区来传输的。 2. 通道(Channel):Java NIO中的通道是一种对象,它可以用来读取和写入数据。通道类似于流,但是它们可以被双向读写,并且可以同时处理多个线程。 3. 选择器(Selector):Java NIO中的选择器是一种对象,它可以用来监视多个通道的事件(如读写就绪),从而实现单线程处理多个通道的能力。 4. 文件处理:Java NIO中提供了一组文件处理的API,包括了文件读写、文件锁、文件映射等功能。 Java NIO源码解析需要深入研究Java NIO的实现细节,包括了缓冲区的实现、通道的实现、选择器的实现等。其中,缓冲区的实现是Java NIO的核心,也是最复杂的部分。Java NIO中的缓冲区是通过JNI(Java Native Interface)和Java堆内存来实现的,它提供了高效的数据传输方式,但是也带来了一些复杂性。通道的实现是基于底层的操作系统文件描述符来实现的,它提供了高效的IO操作方式,但是也需要考虑系统平台的差异性。选择器的实现是基于操作系统提供的事件驱动机制来实现的,它可以实现单线程同时处理多个通道的能力,但是也需要考虑系统平台的差异性。 总之,Java NIO源码解析需要深入理解Java NIO的核心概念和实现细节,这样才能更好地理解Java NIO的工作机制,并且能够在实际开发中灵活运用Java NIO的各种功能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值