java从jdk1.4后就引入了java NIO机制:

NIO的显著特点就是通道(channel)、缓冲(buffer)、选择器(selector),NIO机制中添加了传统I/O机制中没有的非阻塞调用(这对于网络通信很有用,可以有效利用CPU),但是这个只能对于网络通道(Socketchannel)才适用,filechannel还是阻塞调用。

我们现在专门分析的是java中的文件I/O机制,而不管网络的socket通信机制。

Java中传统的文件系统I/O机制是Filesystem和File,java中的Filesystem是java中的内部类,不提供对外的显示特性,File类中的包含了Filesystem的对象,从而对于File的操作,比如rename、create etc 都转成成java中的内部类Filesystem的操作。下面的是java中的Filesystem的抽象类:

abstract class FileSystem {

/**
     * Return the FileSystem object representing this platform's local
     * filesystem.
     */
    public static native FileSystem getFileSystem();

/* -- Normalization and construction -- */

/**
     * Return the local filesystem's name-separator character.
     */
    public abstract char getSeparator();

/**
     * Return the local filesystem's path-separator character.
     */
    public abstract char getPathSeparator();
  
   。。。。。。

}

每个操作系统中都有一个具体的文件系统,而在windows下,通过Filesystem的getFilesystem()操作获取本地文件系统,win32Filesystem; 而对于linux系统下,获取的是unixFilesystem;

而java中传统的I/O机制中的File对象,通过包含Filesystem对象,来达到对于文件系统下文件的管理操作create、delete、rename等。而关于文件的I/O数据流,输入和输出,采用的是Fileinputstream和Fileoutputstream。下面以Fileinputstream为例,Fileinputstream中的文件操作函数包括如下:

private native void open(String name) throws FileNotFoundException;

/**
     * Reads a byte of data from this input stream. This method blocks
     * if no input is yet available.
     *
     * @return     the next byte of data, or <code>-1</code> if the end of the
     *             file is reached.
     * @exception  IOException  if an I/O error occurs.
     */
    public int read() throws IOException {
        Object traceContext = IoTrace.fileReadBegin(path);
        int b = 0;
        try {
            b = read0();
        } finally {
            IoTrace.fileReadEnd(traceContext, b == -1 ? 0 : 1);
        }
        return b;
    }

private native int read0() throws IOException;

/**
     * Reads a subarray as a sequence of bytes.
     * @param b the data to be written
     * @param off the start offset in the data
     * @param len the number of bytes that are written
     * @exception IOException If an I/O error has occurred.
     */
    private native int readBytes(byte b[], int off, int len) throws IOException;
 
     public native long skip(long n) throws IOException;

等,上面是几个重要的函数,每次File读取操作的时候都有个文件读取位置,在linux文件系统下是文件描述符FileDescriptor,而windows系统下是handler,读取位置是通过FileDescriptor或者Handler来完成的,每次只能从上一次的位置读取文件操作。

但是Java中的NIO(New I/O)中引入了FileChannel,在FileChannel中有如下新特性:

  1. 字节读取可以以相对位置读取,也可以以绝对位置读取
  2. 一个文件的区域可以直接映射进入到内存中去
  3. 字节可以从一个文件传送到另外一个文件,通过transferto方法,直接在内核空间进行文件传输,而不用在用户态和内核态之间来回切换,有效减少了文件传输时间(在linux下有个相应的函数是sendfile,直接是在内核态进行文件传输,而无须在用户态和内核态之间来回进行数据切换)

相应的Filechannel是一个抽象类:

    public  abstract class FileChannel
    extends AbstractInterruptibleChannel
    implements SeekableByteChannel, GatheringByteChannel, ScatteringByteChannel {。。。}

新增加的方法是:
       /**
     * Reads a sequence of bytes from this channel into the given buffer,
     * starting at the given file position.
     *
     * <p> This method works in the same manner as the {@link
     * #read(ByteBuffer)} method, except that bytes are read starting at the
     * given file position rather than at the channel's current position.  This
     * method does not modify this channel's position.  If the given position
     * is greater than the file's current size then no bytes are read.  </p>
     public abstract int read(ByteBuffer dst, long position) throws IOException;
   /**
     * Writes a sequence of bytes to this channel from the given buffer,
     * starting at the given file position.
     *
     * <p> This method works in the same manner as the {@link
     * #write(ByteBuffer)} method, except that bytes are written starting at
     * the given file position rather than at the channel's current position.
     * This method does not modify this channel's position.  If the given
     * position is greater than the file's current size then the file will be
     * grown to accommodate the new bytes; the values of any bytes between the
     * previous end-of-file and the newly-written bytes are unspecified.  </p>
     public abstract int write(ByteBuffer src, long position) throws IOException;
  /**
     * Acquires a lock on the given region of this channel's file.
      public abstract FileLock lock(long position, long size, boolean shared)
        throws IOException;
   /**
     * Forces any updates to this channel's file to be written to the storage
     * device that contains it.
   public abstract void force(boolean metaData) throws IOException;
  /**
     * Transfers bytes from this channel's file to the given writable byte
     * channel.
     * <p> This method is potentially much more efficient than a simple loop
     * that reads from this channel and writes to the target channel.  Many
     * operating systems can transfer bytes directly from the filesystem cache
     * to the target channel without actually copying them.  </p>
    public abstract long transferTo(long position, long count,
                                    WritableByteChannel target)
        throws IOException;
   上述是FileChannel新增的方法。

传统的Java中的I/O机制中的FileInputStream的成员变量:

private final FileDescriptor fd;
   即传统的java文件系统采用的是通过文件描述符的形式来记住文件的存取位置

而java中的NIO机制也是采用类似的机制:

// Used to make native read and write calls
    private static NativeDispatcher nd;

// Memory allocation size for mapping buffers
    private static long allocationGranularity;

// Cached field for MappedByteBuffer.isAMappedBuffer
    private static Field isAMappedBufferField;

// File descriptor
    private FileDescriptor fd;
   上面是一个具体的Filechannel类,FilechannelImpl部分成员变量。

java文件系统中的的NIO与IO的更多相关文章

  1. Java中 NIO与IO的区别

    当学习了Java NIO和IO的API后,一个问题马上涌入脑海: 我应该何时使用IO,何时使用NIO呢?在本文中,我会尽量清晰地解析Java NIO和IO的差异.它们的使用场景,以及它们如何影响您的代 ...

  2. Java中的NIO和IO的对比分析

    总的来说,java中的IO和NIO主要有三点区别: IO NIO 面向流 面向缓冲 阻塞IO 非阻塞IO 无 选择器(Selectors) 1.面向流与面向缓冲 Java NIO和IO之间第一个最大的 ...

  3. Java中的NIO及IO

    1.概述 Java NIO(New IO) 是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的Java IO API.NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同, ...

  4. java中的NIO和IO到底是什么区别?20个问题告诉你答案

    摘要:NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多. 本文分享自华为云社区<jav ...

  5. Java中NIO和IO区别和适用场景

    NIO是为了弥补IO操作的不足而诞生的,NIO的一些新特性有:非阻塞I/O,选择器,缓冲以及管道.管道(Channel),缓冲(Buffer) ,选择器( Selector)是其主要特征. 概念解释: ...

  6. Java 7 中 NIO.2 的使用——第四节 文件和目录

    Files类提供了很多方法用于检查在于你真正实际去操作一个文件或目录.这些方法强烈推荐,也非常有用,也能避免很多异常的发生.例如,一个很好的习惯就是在你试着移动一个文件从一个地方到另一个地方的时候,先 ...

  7. Java 7 中 NIO.2 的使用——第一节 Path 类的使用

    路径隶属于文件系统,实际上它是存储和组织媒体文件的格式,通常在一块或多块硬盘设备上,以便于非常容易地检索.文件系统可以通过  java.nio.file.FileSystems 这个final 类来访 ...

  8. java nio 与io区别

    转自:http://blog.csdn.net/keda8997110/article/details/19549493 当学习了Java NIO和IO的API后,一个问题马上涌入脑海: 我应该何时使 ...

  9. java nio(non-blocking io)简介及和io

    在 Java1.4之前的I/O系统中,提供的都是面向流的I/O系统,系统一次一个字节地处理数据,一个输入流产生一个字节的数据,一个输出流消费一个字节 的数据,面向流的I/O速度非常慢,而在Java 1 ...

随机推荐

  1. 基于easyUI实现系统日志管理

    此文章是基于 EasyUI+Knockout实现经典表单的查看.编辑 一. 相关文件介绍 1. log.jsp:系统日志管理界面 <!DOCTYPE html PUBLIC "-//W ...

  2. 基于easyUI实现权限管理系统(二)——菜单导航

    此文章是基于 EasyUI+Knockout实现经典表单的查看.编辑 一. 相关文件介绍 1. menu.jsp:菜单导航主界面 <!DOCTYPE html PUBLIC "-//W ...

  3. content-box跟border-box的区别

    content-box: padding和border不被包含在定义的width和height之内.对象的实际宽度等于设置的width值和border.padding之和,即 ( Element wi ...

  4. Linux符设备驱动编程

    加入内核源码树外 ① 建立两个文件scull.c,scull.h,以及Makefile文件 Makefile文件 ② 用make进行编译,生成scull.ko驱动程序模块 ③ 把scull.ko模块加 ...

  5. Tomcat中server.xml文件内各节点详解

    由于 Tomcat 基于 Java,实际上在各种 Linux 发行版里的配置方法都大同小异,只是我看见在 Arch Linux 环境里搭建 Tomcat 的文章比较少,所以在 Arch Linux 实 ...

  6. sudo:*:command not found

    原因:执行sudo后,sudo会根据visudo里面配置的secure_path来找寻命令,所以sudo尽量使用绝对路径 sudo bash-c "echo $PATH"也可以看到 ...

  7. WIN7与WIN10 安装

    ---恢复内容开始--- 开始的操作系统是黑白屏的DOS,随着光标的一闪一闪并逐渐后移,一条条指令输入电脑,并执行相关指令完成任务.慢慢的,视窗操作系统最初是基于DOS的windows 9X内核WIN ...

  8. js中公有方法、特权方法、静态方法

    1.公有属性和公有方法 1 2 3 4 5 6 7 8 9 function User(name,age){   this.name = name;//公有属性   this.age = age; } ...

  9. 【深入理解JAVA虚拟机】第三部分.虚拟机执行子系统.3.函数调用与执行

    这章原名叫“虚拟机字节码执行引擎”,实际就是讲的函数如何调用和执行的. 1.概述 “虚拟机”是一个相对于“物理机”的概念,这两种机器都有代码执行能力, 其区别是物理机的执行引擎是直接建立在处理器. 硬 ...

  10. 代码大全读书笔记 Part 1

    简单的看了前言,印象最深的还是这本书崇尚"绝不注水"的原则.现实生活中,不仅仅有注水牛肉,瘦肉精的猪肉,很多书籍也是东拼西凑来的内容,不注水的厚书,是十分令人期待的. 第一章:欢迎 ...