JAVA中的NIO(二)

一、内存文件映射



内存文件映射允许我们创建和修改那些因为太大而不能放入内存中的文件。有了内存文件映射,我们就可以假定整个文件都在内存中,而且可以完全把文件当作数组来访问。

package com.dy.xidian;

import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

public class LargeMappedFiles {
    static int length = 0x8FFFFFF;
    public static void main(String[] args) throws Exception {
        @SuppressWarnings("resource")
        MappedByteBuffer out = new RandomAccessFile("test.dat", "rw")
                .getChannel().map(FileChannel.MapMode.READ_WRITE, 0, length);
        for (int i = 0; i < length; i++)
            out.put((byte) ‘x‘);
        System.out.println("Finished writing");
        for (int i = length / 2; i < length / 2 + 6; i++)
            System.out.print((char) out.get(i));
    }
}

map中的0表示从文件的起始位置开始映射,映射的大小为length(128MB)。MappedByteBuffer是直接缓冲区(JVM对直接缓冲区的内容会直接进行IO操作,如果缓冲区是非直接的,JVM会先将用户缓冲区的数据copy到自己的缓冲区,在对自己的缓冲区进行IO操作),

所以MappedByteBuffer对大文件的操作速度要比普通的IO流快。MappedByteBuffer继承自ByteBuffer,所以我们对ByteBuffer的操作都适用于ByteBuffer。

二、对映射文件的部分加锁



  文件映射通常应用于极大的文件。我们可能需要对这种巨大的文件进行部分加锁,以便其它进程可以修改文件中未被加锁的部分。例如:数据库就是这样吗,因此多个用户可以同时访问它

package com.dy.xidian;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;

public class LockingMappedFiles {
    static final int LENGTH = 0X8FFFFFF;
    static FileChannel fc;
    @SuppressWarnings("resource")
    public static void main(String[] args) throws Exception {
        fc = new RandomAccessFile("test.dat", "rw").getChannel();
        MappedByteBuffer out = fc
                .map(FileChannel.MapMode.READ_WRITE, 0, LENGTH);
        for (int i = 0; i < LENGTH; i++)
            out.put((byte) ‘x‘);
        new LockAndModify(out, 0, LENGTH / 3);
        new LockAndModify(out, LENGTH / 2, LENGTH / 2 + LENGTH / 4);
    }
    private static class LockAndModify extends Thread {
        private ByteBuffer buff;
        private int start, end;

        LockAndModify(ByteBuffer buff, int start, int end) {
            super();
            this.start = start;
            this.end = end;
            this.buff = buff;
            buff.limit(end);
            buff.position(start);
            //创建一个新缓冲区标识对象
            //该对象的position=0,limit和capacity等于原缓冲区剩余字节数。
            buff = buff.slice();
            start();
        }

        public void run() {
            try {
                // 获取通道上的锁,指定加锁的起始位置和结束位置
                // 将锁设置为独占锁
                FileLock fl = fc.lock(start, end, false);
                System.out.println("Locked: " + start + " to " + end);
                while (buff.position() < buff.limit() - 1)
                    buff.put((byte) (buff.get() + 1));
                fl.release();
                System.out.println("Released: " + start + " to " + end);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

3.GZIP的使用范例


package com.dy.xidian;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class GZIPcompress {
    public static void main(String[] args) throws IOException {
        if (args.length == 0) {
            System.out.println("Usage: \n\tGZIPcompress file\n"
                    + "\tUses GZIP compress to compress "
                    + "the file to test.gz");
            System.exit(1);
        }
        BufferedReader in = new BufferedReader(new FileReader(args[0]));
        BufferedOutputStream out = new BufferedOutputStream(
                new GZIPOutputStream(new FileOutputStream("test.gz")));
        System.out.println("Writing file");
        int c;
        while ((c = in.read()) != -1) {
            out.write(c);
        }
        in.close();
        out.close();
        System.out.println("Reading file");
        BufferedReader in2 = new BufferedReader(new InputStreamReader(
                new GZIPInputStream(new FileInputStream("test.gz"))));
        String s;
        while ((s = in2.readLine()) != null)
            System.out.println(s);
        in2.close();
    }
}
时间: 2024-08-10 10:17:11

JAVA中的NIO(二)的相关文章

JAVA 中BIO,NIO,AIO的理解

JAVA 中BIO,NIO,AIO的理解 博客分类: 网络编程 [转自]http://qindongliang.iteye.com/blog/2018539 在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解.具体如下: 序号 问题 1 什么是同步? 2 什么是异步? 3 什么是阻塞? 4 什么是非阻塞? 5 什么是同步阻塞? 6 什么是同步非阻塞? 7 什么是异步阻塞? 8 什么是异步非阻塞? 散仙不才,在查了一部分资料后,愿试着以通俗易懂的方式解释下这几个名词.如有不足之处,还

Java中的NIO和IO的对比分析

总的来说,java中的IO和NIO主要有三点区别: IO                  NIO 面向流     面向缓冲 阻塞IO  非阻塞IO  无   选择器(Selectors) 1.面向流与面向缓冲 Java NIO和IO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的. Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方.此外,它不能前后移动流中的数据.如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区. Java

Java中的NIO基础知识

上一篇介绍了五种NIO模型,本篇将介绍Java中的NIO类库,为学习netty做好铺垫 Java NIO 由3个核心组成,分别是Channels,Buffers,Selectors.本文主要介绍着三个部分. Channel 所有的I/O都从一个Channel开始.通道与流不同,通道是双向的,流是单向的. 即可以从通道中读取数据,也可以写数据到通道里 . 读的话,是从通道读取数据到缓冲区,写的话是从缓冲区写入数据到通道. 四种通道: FileChannel.从文件中读写数据 DatagramCha

java中封装类(二)

java中的数字类型包括 Byte,Short,Integer,Long,Float,Double.其中前四个是整数,后两个是浮点数. 在说java中数字类型之前先来看看它们统一的基类Number. package java.lang; public abstract class Number implements java.io.Serializable { public abstract int intValue(); public abstract long longValue(); pu

java中的NIO基础

在jdk1.4中,加入了一个新的包,java.nio.*,这个包引入了新的javaI/O库,目的是为了提高速度,实际上,旧的I/O包也使用nio重新实现过. 相对于io,nio中的这个n代表什么呢?<java编程思想>直接把小标题取名为"新I/O",另一种说法是Non-blocking的首字母,不管怎样,nio也确实是一种新的处理非阻塞的IO. NIO的几个核心组成部分:Chennels(通道),Buffers(缓存),Selectors(选择器). 我们可以把通道(Cha

Java中的Annotation (二、自定义Annotation)

今天学习如何开发一个自定义的Annotation.要想使Annotation有意义,还需要借用前几天学习的反射机制. 下面就开始今天的学习吧. Annotation的定义格式.它类似于新创建一个接口类文件,但为了区分,我们需要将它声明为 @interface public @interface Annotation名称{ 数据类型 变量名称(); } 下面声明了一个Annotation public @interface MyAnnotation { } 使用这个Annotation @MyAn

Java中的NIO

Java NIO非堵塞技术实际是采取Reactor模式,或者说是Observer模式为我们监察I/O端口, 如果有内容进来,会自动通知我们,这样,我们就不必开启多个线程死等,从外界看,实现了流畅的I/O读写,不堵塞了. NIO 有一个主要的类Selector,这个类似一个观察者,只要我们把需要探知的socketchannel告诉Selector,我们接着做别的事情,当有事件发生时,他会通知我们,传回一组SelectionKey,我们读取这些Key,就会获得我们刚刚注册过的socketchanne

Java中BIO,NIO,AIO的理解

在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解.具体如下: 1 什么是同步? 2 什么是异步? 3 什么是阻塞? 4 什么是非阻塞? 5 什么是同步阻塞? 6 什么是同步非阻塞? 7 什么是异步阻塞? 8 什么是异步非阻塞? 先来举个实例生活中的例子: 如果你想吃一份宫保鸡丁盖饭: 同步阻塞:你到饭馆点餐,然后在那等着,还要一边喊:好了没啊! 同步非阻塞:在饭馆点完餐,就去遛狗了.不过溜一会儿,就回饭馆喊一声:好了没啊! 异步阻塞:遛狗的时候,接到饭馆电话,说饭做好了,让您亲自

了解一下JAVA中的NIO模块

网上资料大把,但要写写代码,我这个年纪的人才有一点点记忆了.. 参考URL: http://blog.csdn.net/wuxianglong/article/details/6612282 package com.cg.io; import java.io.*; import java.nio.*; import java.nio.channels.*; public class TestIntBuffer { static private final byte message[] = {83