import java.io.*;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.CRC32;

public class Test {
    public static void main(String[] args){
        MemoryMapTest.test();
    }
}

/*
    2.6 内存映射文件

    2.6.1 内存映射文件的性能

    java.nio包使用内存映射的过程:
        1.得到一个通道
            FileChannel channel = FileChannel.open(path,options);
        2.通过map方法从这个通道中获得一个ByteBuffer,可以指定要映射的文件区域与模式
            FileChannel.MapMode.READ_ONLY:
            FileChannel.MapMode.READ_WRITE:
            FileChannel.MapMode.PRIVATE:
        3.通过ByteBuffer读写数据

            //顺序遍历缓冲区所有字节
            while(buffer.hasRemaining()){
                byte b = buffer.get();
                ...
            }

            //随机访问缓冲区字节
            for(int i =0; i<buffer.limit(); i++)
                byte b = buffer.get(i);
                ...
            }

            //读写字节数组
            get(byte[] bytes)
            get(byte[] bytes, int offset, int len)

            getInt,getLong,getShort,getChar,getFloat,getDouble,order

            buffer.order(ByteOrder.LITTLE_ENDIAN);

 */
class MemoryMapTest{
    /*
        待会找到Java编程思想中关于CRC32的用法,对比一下

            CheckedOutputStream csum = new CheckedOutputStream(f, new Adler32());
            ZipOutputStream zos = new ZipOutputStream(csum);
     */
    public static long checksumInputStream(Path filename){
        try(InputStream in = Files.newInputStream(filename)) {
            CRC32 crc = new CRC32();
            int c;
            while((c=in.read())!=-1){
                crc.update(c);
            }
            return crc.getValue();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0L;
    }

    public static long checksumBufferedInputStream(Path filename){
        try(InputStream in = new BufferedInputStream(Files.newInputStream(filename))){
            CRC32 crc = new CRC32();
            int c;
            while((c=in.read())!=-1){
                crc.update(c);
            }
            return crc.getValue();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0L;
    }

    public static long checksumRandomAccseeFile(Path filename){
        try(RandomAccessFile file = new RandomAccessFile(filename.toFile(),"r")) {

            long length = file.length();
            CRC32 crc = new CRC32();

            for(long p=0;p<length;p++){
                file.seek(p);
                int c= file.readByte();
                crc.update(c);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0L;
    }

    public static long checksumMappedFile(Path filename){
        try(FileChannel channel = FileChannel.open(filename)) {

            CRC32 crc = new CRC32();
            int length = (int)channel.size();
            MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY,0,length);

            for (int p = 0; p < length; p++) {
                int c = buffer.get(p);
                crc.update(c);
            }
            return crc.getValue();

        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0L;
    }

    public static void test(){
        Path filename = Paths.get("./temp.tmp");

        //InputStream
        System.out.println("InputStream:");
        long start = System.currentTimeMillis();
        long crcValue = checksumInputStream(filename);
        long end = System.currentTimeMillis();
        System.out.println(Long.toHexString(crcValue));
        System.out.println((end-start)+" milliseconds");

        //RandomAccessFile
        System.out.println("RandomAccessFile:");
        start = System.currentTimeMillis();
        crcValue = checksumRandomAccseeFile(filename);
        end = System.currentTimeMillis();
        System.out.println(Long.toHexString(crcValue));
        System.out.println((end-start)+" milliseconds");

        //BufferedInputStream
        System.out.println("BufferedInputStream:");
        start = System.currentTimeMillis();
        crcValue = checksumBufferedInputStream(filename);
        end = System.currentTimeMillis();
        System.out.println(Long.toHexString(crcValue));
        System.out.println((end-start)+" milliseconds");

        //Mapped
        System.out.println("InputStream:");
        start = System.currentTimeMillis();
        crcValue = checksumMappedFile(filename);
        end = System.currentTimeMillis();
        System.out.println(Long.toHexString(crcValue));
        System.out.println((end-start)+" milliseconds");
    }
}

/*
    2.6.2 缓冲区数据结构

    每个缓冲区都具有:
        1.一个容量,它永远不能被改变
        2.一个读写位置,写一个值将在此读写
        3.一个界限,超过它进行读写是没有意义的
        4.一个可选的标记,用于重复一个读入或写出操作

    0<=标记<=位置<=界限<=容量
 */

/*
    2.6.3 文件加锁机制

        FileLock lock = channel.lock();
        FileLock lock = channel.tryLock();

        FileLock lock(long start,long size,boolean shared)
        FileLock tryLock(long start, long size,boolean shared)

        如果shared的标志为false,则锁定文件的目的是读写,如果为true,则这是一个共享锁,
        它允许多个进程从文件中读入,并阻止任何进程获得独占的锁。调用FileLock类的isShared
        方法可以查询你持有的锁的类型。
 */

《Java核心技术卷二》笔记

Java 内存映射文件的更多相关文章

  1. java内存映射文件

    内存映射文件能够让我们创建和修改大文件(大到内存无法读入得文件),对于内存映射文件,我们可以认为是文件已经全部被读入到内存当中,然后当成一个大的数字来访问,简化修改文件的代码. 1.directBuf ...

  2. 目录_Java内存分配(直接内存、堆内存、Unsafel类、内存映射文件)

    1.Java直接内存与堆内存-MarchOn 2.Java内存映射文件-MarchOn 3.Java Unsafe的使用-MarchOn 简单总结: 1.内存映射文件 读文件时候一般要两次复制:从磁盘 ...

  3. 内存映射文件(Memory-Mapped File)

    Java Memory-Mapped File所使用的内存分配在物理内存而不是JVM堆内存,且分配在OS内核. 1: 内存映射文件及其应用 - 实现一个简单的消息队列 / 计算机程序的思维逻辑 在一般 ...

  4. 使用Java内存映射(Memory-Mapped Files)处理大文件

    >>NIO中的内存映射 (1)什么是内存映射文件内存映射文件,是由一个文件到一块内存的映射,可以理解为将一个文件映射到进程地址,然后可以通过操作内存来访问文件数据.说白了就是使用虚拟内存将 ...

  5. 《Java核心技术卷二》笔记(二)文件操作和内存映射文件

    文件操作 上一篇已经总结了流操作,其中也包括文件的读写.文件系统除了读写以为还有很多其他的操作,如复制.移动.删除.目录浏览.属性读写等.在Java7之前,一直使用File类用于文件的操作.Java7 ...

  6. Java NIO之内存映射文件——MappedByteBuffer

    大多数操作系统都可以利用虚拟内存实现将一个文件或者文件的一部分"映射"到内存中.然后,这个文件就可以当作是内存数组来访问,这比传统的文件要快得多. 内存映射文件的一个关键优势是操作 ...

  7. Java NIO 内存映射文件

    Java NIO 内存映射文件 @author ixenos 文件操作的四大方法 前提:内存的访问速度比磁盘高几个数量级,但是基本的IO操作是直接调用native方法获得驱动和磁盘交互的,IO速度限制 ...

  8. Java利用内存映射文件实现按行读取文件

    我们知道内存映射文件读取是各种读取方式中速度最快的,但是内存映射文件读取的API里没有提供按行读取的方法,需要自己实现.下面就是我利用内存映射文件实现按行读取文件的方法,如有错误之处请指出,或者有更好 ...

  9. Java编程的逻辑 (61) - 内存映射文件及其应用 - 实现一个简单的消息队列

    本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...

随机推荐

  1. SimpleMembershipProvider 的 MySql 实现

    认 证我一直用的是微软的 Membership 体系,看 MySql 也实现了对应的 Provider,在新建立了一个 MVC4 项目后,把 Provider 一改就直接启动,然后就出错了.异常是“T ...

  2. postgresql Java JDBC 一次性传入多个参数到 in ( ?) - multple/list parameters

    经常不清楚需要传入多少个参数到 IN () 里面,下面是简单方法: 方法 1 - in ( SELECT * FROM unnest(?)) ) Integer[] ids={1,2,3};      ...

  3. 关于qtcreator+vs2008+CDB调试太卡的问题研究(载入符号表,以及VS调试器的注册表信息)

    在刚接触Qt时,对于较大的项目,用qtcreator + vs + cdb 调试时,启动很慢并且单步运行时也经常会出现卡住半分钟以上的情况,一直没有解决.在需要debug的时候大多会在vs2008上安 ...

  4. 浅谈js闭包(closure)

    相信很多从事js开发的朋友都或多或少了解一些有关js闭包(closure)的知识. 本篇文章是从小编个人角度,简单地介绍一下有关js闭包(closure)的相关知识.目的是帮助一些对js开发经验不是很 ...

  5. 统计插件,Highcharts,以及modelformset

    一.modelfromset组件 1.作用:用于批量处理多个表单 form表单对应的组件是formset Modelform对应的组件是modelformset 2.引入 From django.fo ...

  6. oracle11g安装时出现程序未找到文件解决办法

    在安装的最后可能会出现如下问题 解决办法如下 将win64_11gR2_database_2of2中的\win64_11gR2_database_2of2\database\stage\Compone ...

  7. 前端自动化工具gulp入门基础

    gulp是前端开发过程中经常要用到的工具,非常值得花时间去掌握.利用gulp,我们可以使产品流程脚本化,节约大量的时间,有条不紊地进行业务开发.本文简单讲一下入门gulp需要掌握的东西. 安装gulp ...

  8. vue-cli3.x npm create projectName 报错: Unexpected end of JSON input while parsing near......

    npm 版本与node版本还有webpack版本之间的问题 清理缓存,“ npm cache clean --force " 一切OK

  9. 深入V8引擎-AST(1)

    没办法了,开坑吧,接下来的几篇会讲述JavaScript字符串源码在v8中转换成AST(抽象语法树)的过程. JS代码在V8的解析只有简单的几步,其中第一步就是将源字符串转换为抽象语法树,非常类似于v ...

  10. Spring Bean的3种装配方式

    Bean常用的装配方式有3种: 基于xml的装配 基于Annotation(注解)的装配 基于Java类的装配 基于xml的装配 在xml文件中配置Bean. 如果依赖很多,xml配置文件会很臃肿,后 ...