Java NIO详解及实例和源码下载(一)

来源:互联网 发布:网络远程正规吗 编辑:程序博客网 时间:2024/05/17 23:18
  • 1
    CharBuffer类
public class CharBufferTest {    public static void main(String[] args) {        CharBuffer charBuffer = CharBuffer.allocate(8);        printlnStr("capacity="+charBuffer.capacity());        printlnStr("limit="+charBuffer.limit());        printlnStr("postion="+charBuffer.position());        charBuffer.put("a");        charBuffer.put("b");        charBuffer.put("c");        printlnStr("==================");        printlnStr("capacity="+charBuffer.capacity());        printlnStr("limit="+charBuffer.limit());        printlnStr("postion="+charBuffer.position());        /*         * 调用flip方法之前获取数据,获取不到。         * 原因在于get方法,默认返回的是当前position所在位置的数据。         * flip方法之前,当前的position的位置是3  可以看到输出结果中position值。         * 而此时位置3的值为空,所以获取不到值         */        printlnStr("第一个="+charBuffer.get());        charBuffer.flip();        printlnStr("==================");        printlnStr("capacity="+charBuffer.capacity());        printlnStr("limit="+charBuffer.limit());        printlnStr("postion="+charBuffer.position());        printlnStr("==================");        printlnStr("第一个="+charBuffer.get());        charBuffer.clear();        printlnStr("capacity="+charBuffer.capacity());        printlnStr("limit="+charBuffer.limit());        printlnStr("postion="+charBuffer.position());    }    private static void printlnStr(String str){        System.out.println(str);    }}

结果:
这里写图片描述
通过allocate()方法创建的Buffer对象是普通Buffer,ByteBuffer还提供了一个allocateDirect()方法类创建直接Buffer。直接Buffer的创建成本比普通Buffer的创建成本高,但直接Buffer的读取效率高!
也就是说直接Buffer适用于长期生存期的Buffer,而不适用于短生存期的Buffer.并且只有ByteBuffer才提供了allocateDirect()方法。

  • 2
    FileChannel类
package com.yin.nio;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.nio.MappedByteBuffer;import java.nio.channels.FileChannel;import java.nio.channels.FileChannel.MapMode;public class FileChannelTest {    public static void main(String[] args) {        String pathin = ".\\src\\com\\yin\\nio\\FileChannelTest.java";        String pathout = "a.txt";        File filein = new File(pathin);        File fileout = new File(pathout);        FileInputStream fileInputStream = null;        FileOutputStream fileOutputStream = null;        try {            fileInputStream = new FileInputStream(filein);            fileOutputStream = new FileOutputStream(fileout);            FileChannel fileChannelIn = fileInputStream.getChannel();            FileChannel fileChannelOut = fileOutputStream.getChannel();            MappedByteBuffer mappedByteBuffer = fileChannelIn.map(MapMode.READ_ONLY, 0, filein.length());            fileChannelOut.write(mappedByteBuffer);        } catch (Exception e) {            e.printStackTrace();        }finally{            try {                if (fileInputStream != null) {                    fileInputStream.close();                }                if (fileOutputStream != null) {                    fileOutputStream.close();                }            } catch (IOException e) {                e.printStackTrace();            }        }    }}

结果图:
这里写图片描述

  • 3
    文件锁
public class FileLockTest {    public static void main(String[] args) {        FileChannel fileChannel = null;        try {            fileChannel = new FileOutputStream("a.txt").getChannel();            FileLock fileLock = fileChannel.tryLock();            Thread.sleep(10000);            fileLock.release();        } catch (Exception e) {            e.printStackTrace();        }finally{            try {                if (fileChannel != null) {                    fileChannel.close();                }            } catch (IOException e) {                e.printStackTrace();            }        }    }}

文件锁:可以有效的阻止多个进程并发修改同一个文件。
lock()试图锁定某个文件,如果无法得到文件锁,程序一直阻塞。
tryLock()尝试锁定某个文件,它将直接返回而不是阻塞,如果获得了文件锁,该方法则返回该文件锁,否则返回null。
lock(long postion, long size, boolean shared)对文件从postion开始,长度为size的内容加锁,该方法是阻塞式的。
tryLock(long postion, long size,boolean shared) 非阻塞式的加锁方法,参数同上。
当参数shared为true时,寿命该锁是一个共享锁,他将允许多个进程来读取文件,但阻止其他进程获得对该文件的排他锁。
当参数为false时,表明该锁是一个排他锁,他将锁住对该文件的读写。程序可以调用FileLock的isShared来判断它获得的锁是否是共享锁。

  • 4
    Paths类 Path类
public class PathsTest {    public static void main(String[] args) {        Path path = Paths.get(".");        PrintStr("path里面包含的路径数="+path.getNameCount());        PrintStr("获取根路径="+path.getRoot());        Path absolutePath = path.toAbsolutePath();        PrintStr("获取绝对路径="+absolutePath);        PrintStr("absolutePath的根路径="+absolutePath.getRoot());        PrintStr("absolutePath包含的路径数="+absolutePath.getNameCount());        PrintStr("绝对路径的第三个名字="+absolutePath.getName(3).toString());        Path path2 = Paths.get("D:", "Program Files (x86)","ADT");        PrintStr(path2.toString());    }    private static void PrintStr(String str){        System.out.println(str);    }}

结果:
这里写图片描述
结果中的路径数表示的是当前目录的路径数量,例如“.”表示当前路径,它的路径数就是1。再如,“D:/test/java”这个路径数就是2。再对照上面的结果图是不是很明朗了。
还有一点是“绝对路径的第三个名字=JAVAIO”,这个是因为D:\Program Files (x86)\ADT\workspace\JavaIO.中的Program Files (x86)代表0,算下来JavaIO是不是index=3呢?!
- 5

public class FileVisitorTest {    public static void main(String[] args) throws IOException {        Files.walkFileTree(Paths.get("D:\\"),new SimpleFileVisitor<Path>(){            @Override            public FileVisitResult preVisitDirectory(Path dir,                    BasicFileAttributes attrs) throws IOException {                System.out.println("正在访问的路径="+dir);                return FileVisitResult.CONTINUE;            }            @Override            public FileVisitResult visitFile(Path file,                    BasicFileAttributes attrs) throws IOException {                if (file.endsWith("FileVisitorTest.java")) {                    System.out.println("找到目标文件");                    return FileVisitResult.TERMINATE;                }                return FileVisitResult.CONTINUE;            }            @Override            public FileVisitResult visitFileFailed(Path file, IOException exc)                    throws IOException {                return super.visitFileFailed(file, exc);            }            @Override            public FileVisitResult postVisitDirectory(Path dir, IOException exc)                    throws IOException {                System.out.println("访问结束");                return super.postVisitDirectory(dir, exc);            }        });    }}

遍历文件和目录,结果:
这里写图片描述
妈蛋 D盘放了太多文件了,扫描了好几分钟呀 哈哈哈。。。。
不过这个FileVisitor确实好用、强大!!

源码下载

0 0