import java.io.*;
import java.nio.*;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.*;

public class Test {
    public static void main(String[] args) {
//        GetChannel.test();
//        BufferToText.test();
//        AvailableCharSets.test();
//        GetData.test();
//        IntBufferDemo.test();
//        ViewBuffers.test();
//        Endians.test();
//        UsingBuffers.test();
        LargeMapperFiles.test();
    }
}

/*
    将字节存放在ByteBuffer的方法:
        1.通过put方法直接对它们进行填充,填入一个或多个字节,或基本数据类型
        2.通过warp方法将已存在的字节数组包装到ByteBuffer中,一旦如此,就不需要复制
        底层的数组,而是把它作为所产生的ByteBuffer的存储器,称之为数组支持的ByteBuff。
 */

/*
    1.对于只读操作,需要显示静态的allocate方法来分配ByteBuffer
    2.对于read方法,调用read告知FileChannel向ByteBuffer存储字节后,需要调用缓冲器上
    的flip,让它做好让别人读取字节的准备。
    3.对于read方法,如果我们打算用缓冲器执行进一步的read操作,则我们必须调用clear方法
    来为每一个read做好准备
 */

class GetChannel {
    private static final int BSIZE = 1024;

    public static void test() {
        try {
            //FileOutputStream测试
            FileChannel fc1 = new FileOutputStream("./src/data").getChannel();
            fc1.write(ByteBuffer.wrap("Some test".getBytes()));
            fc1.close();

            //FileInputStream测试
            FileChannel fc2 = new FileInputStream("./src/data").getChannel();
            ByteBuffer buff = ByteBuffer.allocate(BSIZE);
            fc2.read(buff);
            buff.flip();
            /*
                这个地方和下一个案例的需求是不同的:
                    这个案例中我需要将buff中的数据一个一个字符的打印出出来,get方法
                    就像迭代器中的next方法,每次调用时都会向后移动一个位置:
                       while (buff.hasRemaining())
                            System.out.println((char)buff.get());

                    下一个案例中,是从文件中读取,当文件所有内容都被读取后,调用read
                    放法,就会在buffer中存入一个-1的值:
                       while (fc1.read(buffer) != -1) {
                            buffer.flip();
                            fc2.write(buffer);
                            buffer.clear();
            }
            }
             */
            while (buff.hasRemaining()) {
                System.out.println((char)buff.get());
            }

            //RandomAccessFile测试
            FileChannel fc3 = new RandomAccessFile("./src/data","rw").getChannel();
            fc3.position(fc3.size());
            fc3.write(ByteBuffer.wrap("Some more".getBytes()));
            fc3.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class ChannelCopy {
    private static final int BSIZE = 1024;

    public static void test() {
        try{
            FileChannel fc1 = new FileInputStream("./src/data").getChannel();
            FileChannel fc2 = new FileOutputStream("./src/data").getChannel();

            ByteBuffer buffer = ByteBuffer.allocate(BSIZE);

            /*
                FileChannel和ByteBuffer的使用逻辑:
                    1.得到FileChannel,也就是书中说的煤矿
                    2.建立ByteBuffer,也就是书中说的卡车
                    3.通知煤矿向卡车转载货物
                    4.使用卡车中的货物
                    5.清空卡车中的货物
             */
            while (fc1.read(buffer) != -1) {
                buffer.flip();
                fc2.write(buffer);
                buffer.clear();
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

/*
    上一个案例并不是理想的使用方式,transferTo和transferFrom则允许我们将一个通道与
    另一个通道直接相连
 */
class TransferTo{
    public static void test() {
        try{
            FileChannel in = new FileInputStream("./src/data").getChannel();
            FileChannel out = new FileOutputStream("./src/data").getChannel();

            //将in中的位置为0,长度为in.size()的数据移动到out这个通道中
            in.transferTo(0,in.size(),out);

            //将in中的位置为0,长度为in.size()的数据移动到out这个通道中
            out.transferFrom(in,0,in.size());

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class BufferToText {
    private static final int BSIZE = 1024;
    public static void test() {

        try {
            //第一步,打开一个文件向里面写点东西
            FileChannel fc1 = new FileOutputStream("./src/data1").getChannel();
            fc1.write(ByteBuffer.wrap("some text".getBytes()));
            fc1.close();

            //第二步,读取这个文件,尝试使用buffer的asCharBuffer进行输出
            FileChannel fc2 = new FileInputStream("./src/data1").getChannel();
            ByteBuffer buffer = ByteBuffer.allocate(BSIZE);
            fc2.read(buffer);
            buffer.flip();
            System.out.println("buffer.asCharBuffer(): "+buffer.asCharBuffer());

            //第三步,使用系统默认的方式解码
            buffer.rewind(); //移动光标到开始部分
            String encoding = System.getProperty("file.encoding");
            System.out.println("encoding: "+encoding);
            System.out.println("Decode use "+encoding+" :"+Charset.forName(encoding).decode(buffer));

            //第四步,写入东西时指定编码方式
            FileChannel fc3 = new FileOutputStream("./src/data2").getChannel();
            fc3.write(ByteBuffer.wrap("some text".getBytes("UTF-16BE")));
            fc3.close();

            //第五步,将写入的东西读出来
            FileChannel fc4 = new FileInputStream("./src/data2").getChannel();
            ByteBuffer buffer4 = ByteBuffer.allocate(BSIZE);
            fc4.read(buffer4);
            buffer4.flip();
            System.out.println("buffer4.asCharBuffer(): "+buffer4.asCharBuffer());

            //第六步,使用CharBuffer进行写
            FileChannel fc5 = new FileOutputStream("./src/data2").getChannel();
            ByteBuffer buffer5 = ByteBuffer.allocate(24);
            buffer5.asCharBuffer().put("some Text");
            fc5.write(buffer5);
            fc5.close();

            //第七步,将写入的内容读出来
            FileChannel fc6 = new FileInputStream("./src/data2").getChannel();
            ByteBuffer buffer6 = ByteBuffer.allocate(BSIZE);
            fc6.read(buffer6);
            buffer6.flip();
            System.out.println("buffer6.asCharBuffer(): "+buffer6.asCharBuffer());

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class AvailableCharSets {
    public static void test() {
        SortedMap<String,Charset> charset = Charset.availableCharsets();

        Iterator<String> iter_name = charset.keySet().iterator();
        while (iter_name.hasNext()) {
            String charsetName = iter_name.next();
            System.out.print(charsetName);

            Set<String> aliases= charset.get(charsetName).aliases();
            Iterator<String> iter_alia = aliases.iterator();

            if(iter_alia.hasNext())
                System.out.print(":");

            while (iter_alia.hasNext()) {
                System.out.print(iter_alia.next()+"  ");
            }

            System.out.println("");
        }
    }
}

class GetData{
    private static final int BSIZE = 1024;

    public static void test() {
        ByteBuffer b = ByteBuffer.allocate(BSIZE);

        //b在创建是会自动分配0
        int i = 0;
        while (i++ < b.limit()) {
            if (b.get() != 0) {
                System.out.println("not zero.");
            }
        }
        System.out.println("i = "+i);

        //存储并读取一个char
        b.rewind();
        b.asCharBuffer().put("Hello");
        char c;
        while ((c = b.getChar()) != 0) {
            System.out.print(c);
        }
        System.out.println();

        //存储并读取一个short
        b.rewind();
        b.asShortBuffer().put((short) 471142);
        System.out.println("b.getShort(): "+b.getShort());

        //存储并读取一个int
        b.rewind();
        b.asIntBuffer().put(992341);
        System.out.println("b.getInt(): "+b.getInt());

        //存储并读取一个long
        b.rewind();
        b.asLongBuffer().put(234141532234L);
        System.out.println("b.getLong(): "+b.getLong());

        //存储并读取一个float
        b.rewind();
        b.asFloatBuffer().put(23414.134f);
        System.out.println("b.getFloat(): "+b.getFloat());

        //存储并读取一个double
        b.rewind();
        b.asDoubleBuffer().put(234.1432234);
        System.out.println("b.getDouble(): "+b.getDouble());

    }
}

class IntBufferDemo{
    private static final int BSIZE = 1024;
    public static void test() {
        ByteBuffer b = ByteBuffer.allocate(BSIZE);
        IntBuffer ib = b.asIntBuffer();

        ib.put(new int[]{1,2,3,4,5});
        System.out.println(ib.get(3));
        System.out.println(ib.get(4));

        ib.put(3, 100);
        System.out.println(ib.get(3));
        System.out.println(ib.get(4));

        System.out.println("Setting a new limit before rewinding the buffer");
        ib.flip();
        while (ib.hasRemaining()) {
            int i = ib.get();
            System.out.println(i);
        }
    }
}

class ViewBuffers {
    public static void test() {
        ByteBuffer b = ByteBuffer.wrap(new byte[]{0,0,0,0,0,0,0,'a'});

        b.rewind();
        System.out.println("ByteBuffer:");
        while (b.hasRemaining()) {
            System.out.println(b.position()+"-->"+b.get()+".");
        }

        b.rewind();
        CharBuffer cb = b.asCharBuffer();
        System.out.println("CharBuffer:");
        while (cb.hasRemaining()) {
            System.out.println(cb.position()+"-->"+cb.get()+".");
        }
    }
}

class Endians {
    public static void test() {
        ByteBuffer b = ByteBuffer.wrap(new byte[12]);
        b.asCharBuffer().put("abcdef");
        System.out.println(Arrays.toString(b.array()));

        b.rewind();
        b.order(ByteOrder.BIG_ENDIAN);
        b.asCharBuffer().put("abcdef");
        System.out.println(Arrays.toString(b.array()));

        b.rewind();
        b.order(ByteOrder.LITTLE_ENDIAN);
        b.asCharBuffer().put("abcdef");
        System.out.println(Arrays.toString(b.array()));
    }
}

class UsingBuffers {
    private static void symmetricScramble(CharBuffer buffer) {
        while (buffer.hasRemaining()) {
            buffer.mark();
            char c1 = buffer.get();
            char c2 = buffer.get();
            buffer.reset();
            buffer.put(c2).put(c1);
        }
    }

    public static void test() {
        char[] data = "UsingBuffers".toCharArray();
        ByteBuffer bb = ByteBuffer.allocate(data.length * 2);
        CharBuffer cb = bb.asCharBuffer();
        cb.put(data);

        System.out.println(cb.rewind());
        symmetricScramble(cb);
        System.out.println(cb.rewind());
        symmetricScramble(cb);
        System.out.println(cb.rewind());
    }
}

class LargeMapperFiles {
    private static final int length = 0X8FFFFFF; //128 MB

    public static void test() {
        try {
            MappedByteBuffer out = new RandomAccessFile("./src/data", "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.println((char)out.get(i));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Java编程思想:NIO知识点的更多相关文章

  1. Java编程思想非主流知识点

    1. Java中的多态性理解(注意与C++区分) Java中除了static方法和final方法(private方法本质上属于final方法,因为不能被子类访问)之外,其它所有的方法都是动态绑定,这意 ...

  2. JAVA编程思想(第四版)学习笔记----4.8 switch(知识点已更新)

    switch语句和if-else语句不同,switch语句可以有多个可能的执行路径.在第四版java编程思想介绍switch语句的语法格式时写到: switch (integral-selector) ...

  3. 《Java编程思想》读书笔记(三)

    前言:三年之前就买了<Java编程思想>这本书,但是到现在为止都还没有好好看过这本书,这次希望能够坚持通读完整本书并整理好自己的读书笔记,上一篇文章是记录的第十一章到第十六章的内容,这一次 ...

  4. Java编程思想总结笔记The first chapter

    总觉得书中太啰嗦,看完总结后方便日后回忆,本想偷懒网上找别人的总结,无奈找不到好的,只好自食其力,尽量总结得最好. 第一章  对象导论 看到对象导论觉得这本书 目录: 1.1 抽象过程1.2 每个对象 ...

  5. Java编程思想总结笔记Chapter 2

    本章介绍Java程序的基本组成部分,体会到Java中几乎一切都是对象. 第二章   一切都是对象 目录: 2.1 用引用操纵对象 2.2 必须由你创建所有对象 2.3 永远不需要销毁对象 2.4 创建 ...

  6. Java 编程思想 Chapter_14 类型信息

    本章内容绕不开一个名词:RTTI(Run-time Type Identification) 运行时期的类型识别 知乎上有人推断作者是从C++中引入这个概念的,反正也无所谓,理解并能串联本章知识才是最 ...

  7. Java编程思想读书笔记(一)【对象导论】

    2018年1月7日15:45:58 前言 作为学习Java语言的经典之作<Java编程思想>,常常被人提起.虽然这本书出版十年有余,但是内容还是很给力的.很多人说这本书不是很适合初学者,我 ...

  8. 异常笔记--java编程思想

    开一个新的系列,主要记一些琐碎的重要的知识点,把书读薄才是目的...特点: 代码少,概念多... 1. 基本概念 异常是在当前环境下无法获得必要的信息来解决这个问题,所以就需要从当前环境跳出,就是抛出 ...

  9. (Java编程思想)Thinking in Java

    1. 为什么突然想去研读<Thinking in Java>? 最近终于下定决心撸了一本<Thinking in Java>第四版,虽然在此之前我就久闻这本书的大名,但一直未曾 ...

  10. 《Java编程思想》阅读笔记二

    Java编程思想 这是一个通过对<Java编程思想>(Think in java)进行阅读同时对java内容查漏补缺的系列.一些基础的知识不会被罗列出来,这里只会列出一些程序员经常会忽略或 ...

随机推荐

  1. SQL Server中 SET 和 SELECT 赋值有什么区别?

    SQL Server 中对已经定义的变量赋值的方式用两种,分别是 SET 和 SELECT.对于这两种方式的区别,SQL Server 联机丛书中已经有详细的说明,但很多时候我们并没有注意,其实这两种 ...

  2. Git基本用法(一)

    使用Git正常的工作流 创建/修改文件 使用git add <file1> <file2> <file3>...将文件添加至本地的缓冲区Index中 使用git c ...

  3. .NET Core RC2在Linux下部署

    前言 目前ASP.NET Core RC2已经正式发布了,可以参考如下链接: https://blogs.msdn.microsoft.com/dotnet/2016/05/06/net-core-r ...

  4. C语言指针学习总结

    上学的时候学习C语言,最烦的就是里面指针,可是指针也恰恰是C语言的灵魂. 最近在重温数据结构的内容,因为大多数据结构的教材都是用C语言描述的,而数据结构中也大量的用到了指针的内容,所以我就在这篇笔记中 ...

  5. select下拉箭头样式重置

    select{ appearance:none; -moz-appearance:none; -webkit-appearance:none; background: url("../ima ...

  6. python算法与数据结构-队列(44)

    一.队列的介绍 队列的定义:队列是一种特殊的线性表,只允许在表的头部(front处)进行删除操作,在表的尾部(rear处)进行插入操作的线性数据结构,这种结构就叫做队列.进行插入操作的一端称为队尾,进 ...

  7. Windows上安装PyV8

    Windows上安装PyV8 在PyPi网站上有Windows的exe格式的包连接, PyPi, Google注意网络是否通畅! 官网地址 Google PyV8 双击安装, 注意, 一般会自动检测P ...

  8. Method com/mysql/jdbc/PreparedStatement.isClosed()Z is abstract 报错解决

    java.lang.AbstractMethodError: Method com/mysql/jdbc/PreparedStatement.isClosed()Z is abstract ----- ...

  9. 大白话五种IO模型

    目录 一.I/O模型介绍 二.阻塞I/O模型 2.1 一个简单的解决方案 2.2 该方案的问题 2.3 改进方案 2.4 改进后方案的问题 三.非阻塞I/O模型 3.1 非阻塞I/O实例 四.多路复用 ...

  10. Hive入门(三)分桶

    1 什么是分桶 上一篇说到了分区,分区中的数据可以被进一步拆分成桶,bucket.不同于分区对列直接进行拆分,桶往往使用列的哈希值进行数据采样.在分区数量过于庞大以至于可能导致文件系统崩溃时,建议使用 ...