`

(七) 新I/O

 
阅读更多

Java SE 1.4引入大量用于改进输入/输出处理机制的特性,它们位于java.nio包中,合称"新I/O"
包含特性:字符集编码器和解码器,非阻塞的I/O,内存映射文件和文件加锁机制。

1.内存映射文件
大多数操作系统可以利用虚拟内存实现将一个文件或文件的一部分"映射"到内存中。然后这个文件就可以当作是内存数组一样地访问,比传统的文件操作要快的多。
对于中等尺寸的文件的顺序读入没有必要使用内存映射。
(1)从文件中获得一个通道(channel),通道是用于磁盘对象的一种抽象,它使我们可以访问诸如内存映射、文件加锁机制以及文件快速数据传递等操作系统特性。
通过getChannel方法获得通道,这个方法已经添加到了FileInputStream、FileOutputStream和RandomAccessFile类中

    FileInputStream in = new FileInputStream(file);
    FileChannel channel = in.getChannel();

 

(2)通过FileChannel类的 map 方法从这个通道中获得一个 MappedByteBuffer 。并可以指定三种文件区域与映射模式
1)FileChannel.MapMode.READ_ONLY:所产生的缓冲区是只读的,任何对该缓冲区写入的尝试都会导致ReadOnlyBufferException异常。
2)FileChannel.MapMode.READ_WRITE:所产生的缓冲区是可写的,任何修改都会在某个时刻写回到文件中。
  注意:其他映射同一个文件的程序可能不能立即看到这些修改,多个程序同时进行文件映射的确切行为是依赖于操作系统的。
3)FileChannel.MapMode.PRIVATE:所产生的缓冲区是可写的,但是任何修改对这个缓冲区来说都是私有的,不会传播到文件中。
(3)通过ByteBuffer类和Buffer超类的方法对缓冲区(MappedByteBuffer 直接字节缓冲区)进行数据读写操作。
1)缓冲区支持顺序和随机数据访问,它有一个可以通过get和put操作来推动的位置。
2)顺序遍历缓冲区中的所有字节:

    while(buffer.hasRemaining()){
        byte b = buffer.get();
    }

 

3)进行随机访问

    for(int i=0;i<buffer.limit();i++){
        byte b = buffer.get(i);
    }
 

4)读写字符数组 get(byte[] bytes) 和 get(byte[] bytes, int offset, int length)
5)其他方法 getInt,getLong,getShort,getChar,getFloat,getDouble,这些方法可以用来读入存储为二进制值的基本类型。
6)Java对二进制数据使用高位在前的排序机制,如果需要处理的文件包含低位在前的二进制数字,使用方法 buffer.order(ByteOrder.LITTLE_ENDIAN);
7)查询缓冲区内当前的字节顺序,调用 ByteOrder b = buffer.order();

 


2.缓冲区数据结构
缓冲区是由具有相同类型的数值构成的数组,Buffer是一个抽象类,它具有众多的具体子类,其中最长用的是ByteBuffer和CharBuffer,包括ByteBuffer,CharBuffer,DoubleBuffer,IntBuffer,LongBuffer和ShortBuffer。
注意:StringBuffer类和缓冲区没有关系。

每个缓冲区具有:
一个容量,它永远不能改变。
一个读写位置,下一个值将在此进行读写。
一个界限,超过它进行读写是没有意义的。
一个可选的标记,用于重复一个读入或写出操作。
这些值满足 : 0<=标记<=位置<=界限<=容量

(1)使用缓冲区的主要目的是执行"写,然后读入"循环。 假设一个缓冲区,一开始位置为0,界限等于容量。不断调用put将值添加到这个缓冲区中,当耗尽所有的数据或写出的数据量达到容量大小时,就切换到读出操作。
(2)这时调用flip方法将界限设置到当前位置,并把位置复位到0。现在在remaining方法返回正数时(返回值为“界限-位置”),不断的调用get。
(3)在将缓冲区中所有的值都读入之后,调用clear使缓冲区为下一次写循环做好准备。clear方法将位置复位到0,并将界限复位到容量。
(4)重新读入缓冲区,使用rewind或mark/reset方法。

 

 

3.文件加锁机制
多个同时执行的文件需要修改同一个文件的情况下,这个文件很容易被破坏。
文件锁可以控制对文件或文件中某个范围的字节的访问,但是文件加锁机制在不同的操作系统之间变化很大
(1)锁定一个文件可以调用FileChannel类的lock或tryLock方法 FileLock lock = channel.lock();  或 FileLock lock = channel.tryLock();
其中lock调用会阻塞直至可获得锁;tryLock将立刻返回,锁不可用的情况下返回null。这个文件将保持锁定状态,直至这个通道关闭,或者在锁上再调用了release方法。
(2)还可以调用锁定文件的一部分 FileLock lock(long start, long size, boolean exclusive) 或 FileLock trylock(long start, long size, boolean exclusive)
如果exclusive标志为true,则锁定文件的目的读写,而如果为false,则这是一个共享锁,允许多个进程从文件中读入,并阻止任何进程获得独占的锁。并非所有的操作系统都支持共享锁,可能请求共享锁返回独占锁,调用FileLock类的isShared方法确认持有锁的类型。
如果锁定了文件的尾部,但文件的长度随后增长,那么增长出来的额外区域是不锁定的,可以使用Long.MAX_VALUE来锁定所有字节。
注意 : 因为文件加锁机制是依赖于操作系统的所以
(1)在某些系统中,文件加锁仅仅是建议性的,如果一个应用未能得到锁,它仍旧可以被另一个应用并发锁定的文件执行写操作。
(2)在某些系统中,不能在锁定一个文件的同时将其映射到内存中。
(3)文件锁是由整个JAVA虚拟机持有的,如果有两个程序是由同一个虚拟机启动的,那么它们不可能每一个都获得一个在同一个文件上的锁。如果对虚拟机一个文件已经持有锁,再调用lock和tryLock时,会抛出OverlappingFileLockException。
(4)在一些系统中,关闭一个通道会释放由Java虚拟机持有的潜在文件上所有的锁,因此同一个加锁文件应避免使用多个锁。
(5)在网络化的文件系统上锁定文件是高度依赖于系统的。应避免使用。

分享到:
评论

相关推荐

    实验七 C++的I/O流(验证性)

    C++的I/O流实验报告 C++的I/O流是计算机编程中一个非常重要的概念,它涉及到输入/输出操作的各种方式和方法。在本实验报告中,我们将对C++的I/O流进行详细的介绍和实验。 一、实验目的和要求 1. 掌握 C++标准流...

    单片机课件 I/O口的扩展部分

    #### 七、I/O操作指令 - **字节数据传送**:通过指令如`MOVPx,A`、`MOVA,Px`等来实现I/O口的数据输入和输出。 - **位操作指令**:包括位传送(`MOV`)、位清零(`CLR`)、位置1(`SETB`)、位取反(`CPL`)等指令,可以对...

    CANopen I/O 总线使用说明-简体中文版.rar

    CANopen是一种基于控制器局域网络(Controller Area Network, CAN)的通信协议,广泛应用于工业自动化领域,特别是分布式I/O系统。这个"CANopen I/O 总线使用说明-简体中文版.rar"压缩包文件提供了关于如何使用...

    I/O并行口直接驱动LED显示.pdf

    I/O 并行口直接驱动 LED 显示 本实验的主要任务是利用 AT89S51 单片机的 P0 端口直接驱动 LED 数码管,实现在数码管上循环显示 0-9 数字。下面将详细介绍实验的实现过程和相关知识点。 1. 实验原理图 实验原理图...

    74LS273扩展I/O口实验

    在本实验中,我们将探索如何利用74LS273作为一个动态锁存器来扩展微处理器的I/O接口,以实现七段LED数码管的控制。这个实验涉及到硬件设计、编程以及模拟仿真,具体涵盖了Proteus软件的使用、汇编语言编程以及微机...

    数码管显示(不同组IO)_IO数码管_I/O驱动数码管显示_

    3. 设置数码管段:根据七段码,通过写入I/O端口来控制数码管各段的亮灭。 4. 更新公共端:如果是动态驱动,需要通过改变公共端的电平来选择要显示的数码管。 5. 控制显示刷新:为了使用户看不到闪烁,需要以足够快...

    java i/0习题

    Java I/O(输入/输出)是Java编程语言中不可或缺的一部分,它允许程序与外部资源进行数据交换,如文件、网络连接、系统硬件等。在Java I/O中,我们使用流(Stream)的概念来处理数据,流是数据传输的通道。本套习题...

    程序设计训练之 Rust 编程语言 第七讲:I/O 与异步编程

    ### 程序设计训练之 Rust 编程语言 第七讲:I/O 与异步编程 #### 输入输出异步编程的概念 本讲主要聚焦于Rust编程语言中的输入输出(I/O)以及异步编程的基本概念和技术。Rust语言因其高效、安全的特点,在系统...

    USB I/O Programming Manual

    《USB I/O编程手册》是Delcom Engineering提供的一份详尽文档,旨在指导开发者如何与Delcom USB I/O设备进行通信。以下是对该手册中关键知识点的深入解析: ### 一、引言 文档首先介绍了Delcom USB I/O设备的通信...

    西南交通大学DSP原理与应用实验五:I/O实验

    西南交通大学DSP原理与应用实验五:I/O实验 一、实验目的: 本实验的主要目的是掌握DSP的I/O操作,了解DSP如何控制CPLD的IO口,并学习如何编写相应的程序来控制LED流水灯和数码管的显示。 二、实验设备: 实验所...

    Java文件I/O操作:读取与写入文件的全面指南

    ### Java文件I/O操作:读取与写入文件的全面指南 #### 一、引言 文件I/O(输入/输出)是编程中的一项基本技能,尤其是在处理数据持久化和系统交互时。Java提供了丰富的API来支持文件的读取和写入操作。本文将详细...

    文件I/O常用函数总结

    在进行文件I/O操作前,我们需要首先打开一个文件或创建一个新的文件。在Linux C中,可以使用`open`函数来完成这一任务: ```c int open(const char *pathname, int flags); int open(const char *pathname, int ...

    一种自适应多核处理器I_O一致性处理方法.pdf

    首先,他们分析了I/O工作负载的访问模式,并归纳出七种I/O数据访问特性。这些特性包括访问频率、访问序列、并发性、数据依赖性等,帮助理解不同I/O应用的需求和行为。 基于这些访问特性,研究者设计了一种动态调整...

    实时操作系统VxWorks下I/O设备驱动程序的编写技巧2

    ### 实时操作系统VxWorks下的I/O设备驱动程序编写技巧 #### 1. 前言 随着技术的发展,嵌入式设备的应用越来越广泛,在通信、自动化等领域扮演着重要角色。传统的操作系统(如Windows、Unix或DOS)由于并非专为实时...

    Power Integrity for I/O Interfaces:With SI/PI Co-Design

    ### Power Integrity for I/O Interfaces: With SI/PI Co-Design #### 一、概述 《Power Integrity for I/O Interfaces: With SI/PI Co-esign》是一本深入浅出地介绍了信号完整性(SI)与电源完整性(PI)联合设计的...

    按键与并行I/O的扩展实用教案.pptx

    【按键与并行I/O的扩展实用教案】 本教案主要探讨了两个核心概念:七段显示器的原理和键盘及其接口,以及如何通过编程实现4*4按键矩阵的检测。七段显示器广泛应用于数字显示,而键盘则作为人机交互的重要接口。 **...

    iosched-master谷歌官方i/o程序

    《谷歌官方I/O程序——iosched-master深度解析》 谷歌官方I/O程序,代码库名为“iosched-master”,是Google每年举办的全球开发者大会(Google I/O)的移动应用源码。这个开源项目不仅展示了Android应用开发的最佳...

Global site tag (gtag.js) - Google Analytics