JAVA NIO 学习总结(下)

4.迭代目录中的文件

4.1迭代该目录下的文件,try语句可以保证目录流最后被正常关闭

/**
 * 遍历本目录底下所有文件和文件夹
 */
public static void directoryStream(Path path){
try(DirectoryStream<Path> paths = Files.newDirectoryStream(path)){
    Iterator<Path> iterator = paths.iterator();

    while(iterator.hasNext())
    System.out.println(iterator.next().toString());
   } catch (IOException e) {
        e.printStackTrace();
   }
}

4.2如果要遍历所有的子孙目录与文件,Files也提供了另外一个方法

 /**
   * 遍历所有子孙目录和文件
   */
public static void walkFileTree(final Path path){
    try {
    Path path1 = Files.walkFileTree(path, new SimpleFileVisitor<Path>(){

    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
    System.out.println(dir.toString());
    return FileVisitResult.CONTINUE;
}

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException{
    System.out.println(file.toString());
    return FileVisitResult.CONTINUE;
}

    @Override
    public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
    return FileVisitResult.CONTINUE;
}

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

5.内存映射文件
利用虚拟内存将文件或文件的一部分映射到内存,没有磁盘的io操作,这比传统的文件操作速度更快。nio中有一个通道概念,从一个文件中获得通道,可以利用这个通道做文件操作。

下面是一个实例demo:

//获得一个文件通道
FileChannel channel = FileChannel.open(path, StandardOpenOption.READ)
//文件的字节大小
long size = channel.size();
//做内存映射操作,决定文件的读取方式,以及文件映射的范围
MappedByteBuffer map = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
//获取映射后的字节
for (int i = 0; i < size; i++)
map.get(i);

它跟传统的文件流操作有对比试验

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.*;

/**
 * 介绍 内存映射文件 nio ,且与其他io进行性能测试
 * Created by panqian on 2017/1/18.
 */
public class FileChannel_1 {
    public static void main(String[] args) {
        Path path = Paths.get("农门长姐.txt");
        FileChannel_1.fileInputStreamRead(path);
        FileChannel_1.fileChannelMapRead(path);
        FileChannel_1.fileBufferedInputStreamRead(path);
        FileChannel_1.fileRandomAccessRead(path);

    }

    /**
     * 文件通道(内存映射文件)
     *
     * @param path
     */
    public static void fileChannelMapRead(Path path) {

        System.out.println("fileChannelMapRead : ");

        long start = System.currentTimeMillis();

        if (path.toFile().exists()) {
            try (FileChannel channel = FileChannel.open(path, StandardOpenOption.READ)) {
                long size = channel.size();
                MappedByteBuffer map = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);

                for (int i = 0; i < size; i++)
                    map.get(i);

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

        long end = System.currentTimeMillis();

        System.out.println("run " + (end - start) + " milliseconds");
    }

    /**
     * 普通输入流
     *
     * @param path
     */
    public static void fileInputStreamRead(Path path) {

        System.out.println("fileInputStreamRead : ");

        long start = System.currentTimeMillis();

        if (path.toFile().exists()) {
            try (InputStream inputStream = Files.newInputStream(path, StandardOpenOption.READ)) {
                int c;
                while ((c = inputStream.read()) != -1) {
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        long end = System.currentTimeMillis();
        System.out.println("run " + (end - start) + " milliseconds");
    }

    /**
     * 带缓冲区的输入流
     *
     * @param path
     */
    public static void fileBufferedInputStreamRead(Path path) {

        System.out.println("fileBufferedInputStreamRead : ");

        long start = System.currentTimeMillis();
        if (path.toFile().exists()) {
            try (BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(path.toFile()))) {
                int c;
                while ((c = bufferedInputStream.read()) != -1) {
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            long end = System.currentTimeMillis();

            System.out.println("run " + (end - start) + " milliseconds");
        }
    }

    /**
     * 随机访问文件(RandomAccessFile的绝大多数功能,但不是全部,已经被JDK 1.4的nio的"内存映射文件(memory-mapped files)"给取代)
     *
     * @param path
     */
    public static void fileRandomAccessRead(Path path) {

        System.out.println("fileRandomAccessRead : ");

        long start = System.currentTimeMillis();

        if (path.toFile().exists()) {
            try (RandomAccessFile accessFile = new RandomAccessFile(path.toFile(), "r")) {
                int c;
                while ((c = accessFile.read()) != -1) {
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        long end = System.currentTimeMillis();
        System.out.println("run " + (end - start) + " milliseconds");
    }
}

实验结果如下:可以看出,内存映射文件和带缓冲区的输入流读取速度都很快,而普通输入流和随机访问文件较慢,体现了nio的优势。

fileInputStreamRead : 
run 6249 milliseconds
fileChannelMapRead : 
run 9 milliseconds
fileBufferedInputStreamRead : 
run 17 milliseconds
fileRandomAccessRead : 
run 4503 milliseconds
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值