Java使用BIO和NIO進行文件操作比較


1、讀文件

package com.zhi.test;

import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.file.Files;
import java.nio.file.Paths;

/**
 * 文件讀取,緩沖區大小(BF_SIZE)對NIO的性能影響特別大,對BIO無影響<br>
 * 10M的文件,BIO耗時87毫秒,NIO耗時68毫秒,Files.read耗時62毫秒
 * 
 * @author 張遠志
 * @since 2020年5月9日19:20:49
 *
 */
public class FileRead {
    /**
     * 緩沖區大小
     */
    private static final int BF_SIZE = 1024;

    /**
     * 使用BIO讀取文件
     * 
     * @param fileName 待讀文件名
     * @return
     * @throws IOException
     */
    public static String bioRead(String fileName) throws IOException {
        long startTime = System.currentTimeMillis();
        try {
            FileReader reader = new FileReader(fileName);

            StringBuffer buf = new StringBuffer();
            char[] cbuf = new char[BF_SIZE];
            while (reader.read(cbuf) != -1) {
                buf.append(cbuf);
            }
            reader.close();
            return buf.toString();
        } finally {
            System.out.println("使用BIO讀取文件耗時:" + (System.currentTimeMillis() - startTime) + "毫秒");
        }
    }

    /**
     * 使用NIO讀取文件
     * 
     * @param fileName 待讀文件名
     * @return
     * @throws IOException
     */
    public static String nioRead1(String fileName) throws IOException {
        long startTime = System.currentTimeMillis();
        try {
            FileInputStream input = new FileInputStream(fileName);
            FileChannel channel = input.getChannel();

            CharsetDecoder decoder = Charset.defaultCharset().newDecoder();
            StringBuffer buf = new StringBuffer();
            CharBuffer cBuf = CharBuffer.allocate(BF_SIZE);
            ByteBuffer bBuf = ByteBuffer.allocate(BF_SIZE);
            while (channel.read(bBuf) != -1) {
                bBuf.flip();
                decoder.decode(bBuf, cBuf, false); // 解碼,byte轉char,最后一個參數非常關鍵
                bBuf.clear();
                buf.append(cBuf.array(), 0, cBuf.position());
                cBuf.compact(); // 壓縮
            }
            input.close();
            return buf.toString();
        } finally {
            System.out.println("使用NIO讀取文件耗時:" + (System.currentTimeMillis() - startTime) + "毫秒");
        }
    }

    /**
     * 使用Files.read讀取文件
     * 
     * @param fileName 待讀文件名
     * @return
     * @throws IOException
     */
    public static String nioRead2(String fileName) throws IOException {
        long startTime = System.currentTimeMillis();
        try {
            byte[] byt = Files.readAllBytes(Paths.get(fileName));
            return new String(byt);
        } finally {
            System.out.println("使用Files.read讀取文件耗時:" + (System.currentTimeMillis() - startTime) + "毫秒");
        }
    }

    public static void main(String[] args) throws IOException {
        String fileName = "E:/source.txt";
        FileRead.bioRead(fileName);
        FileRead.nioRead1(fileName);
        FileRead.nioRead2(fileName);
    }
}

2、寫文件

package com.zhi.test;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;

/**
 * 文件寫<br>
 * 10M的數據,BIO耗時45毫秒,NIO耗時42毫秒,Files.write耗時24毫秒
 * 
 * @author 張遠志
 * @since 2020年5月9日21:04:40
 *
 */
public class FileWrite {
    /**
     * 使用BIO進行文件寫
     * 
     * @param fileName 文件名稱
     * @param content  待寫內存
     * @throws IOException
     */
    public static void bioWrite(String fileName, String content) throws IOException {
        long startTime = System.currentTimeMillis();
        try {
            FileWriter writer = new FileWriter(fileName);
            writer.write(content);
            writer.close();
        } finally {
            System.out.println("使用BIO寫文件耗時:" + (System.currentTimeMillis() - startTime) + "毫秒");
        }
    }

    /**
     * 使用NIO進行文件寫
     * 
     * @param fileName 文件名稱
     * @param content  待寫內存
     * @throws IOException
     */
    public static void nioWrite1(String fileName, String content) throws IOException {
        long startTime = System.currentTimeMillis();
        try {
            FileOutputStream out = new FileOutputStream(fileName);
            FileChannel channel = out.getChannel();
            ByteBuffer buf = ByteBuffer.wrap(content.getBytes());
            channel.write(buf);
            out.close();
        } finally {
            System.out.println("使用NIO寫文件耗時:" + (System.currentTimeMillis() - startTime) + "毫秒");
        }
    }

    /**
     * 使用Files.write進行文件寫
     * 
     * @param fileName 文件名稱
     * @param content  待寫內存
     * @throws IOException
     */
    public static void nioWrite2(String fileName, String content) throws IOException {
        long startTime = System.currentTimeMillis();
        try {
            File file = new File(fileName);
            if (!file.exists()) {
                file.createNewFile();
            }
            Files.write(file.toPath(), content.getBytes(), StandardOpenOption.WRITE);
        } finally {
            System.out.println("使用Files.write寫文件耗時:" + (System.currentTimeMillis() - startTime) + "毫秒");
        }
    }

    public static void main(String[] args) throws IOException {
        String content = FileRead.nioRead2("E:/source.txt");
        String target1 = "E:/target1.txt", target2 = "E:/target2.txt", target3 = "E:/target3.txt";
        FileWrite.bioWrite(target1, content);
        FileWrite.nioWrite1(target2, content);
        FileWrite.nioWrite2(target3, content);
    }
}

3、復制文件

package com.zhi.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Paths;

/**
 * 文件復制<br>
 * 10M的文件,bio耗時56毫秒,nio耗時12毫秒,Files.copy耗時10毫秒
 * 
 * @author 張遠志
 * @since 2020年5月9日17:18:01
 *
 */
public class FileCopy {
    /**
     * 使用BIO復制一個文件
     * 
     * @param target 源文件
     * @param source 目標文件
     * 
     * @throws IOException
     */
    public static void bioCopy(String source, String target) throws IOException {
        long startTime = System.currentTimeMillis();
        try {
            FileInputStream fin = new FileInputStream(source);
            FileOutputStream fout = new FileOutputStream(target);

            byte[] byt = new byte[1024];
            while (fin.read(byt) > -1) {
                fout.write(byt);
            }

            fin.close();
            fout.close();
        } finally {
            System.out.println("使用BIO復制文件耗時:" + (System.currentTimeMillis() - startTime) + "毫秒");
        }
    }

    /**
     * 使用NIO復制一個文件
     * 
     * @param target 源文件
     * @param source 目標文件
     * 
     * @throws IOException
     */
    public static void nioCopy1(String source, String target) throws IOException {
        long startTime = System.currentTimeMillis();
        try {
            FileInputStream fin = new FileInputStream(source);
            FileChannel inChannel = fin.getChannel();
            FileOutputStream fout = new FileOutputStream(target);
            FileChannel outChannel = fout.getChannel();

            inChannel.transferTo(0, inChannel.size(), outChannel);

            fin.close();
            fout.close();
        } finally {
            System.out.println("使用NIO復制文件耗時:" + (System.currentTimeMillis() - startTime) + "毫秒");
        }
    }

    /**
     * 使用Files.copy復制一個文件
     * 
     * @param target 源文件
     * @param source 目標文件
     * 
     * @throws IOException
     */
    public static void nioCopy2(String source, String target) throws IOException {
        long startTime = System.currentTimeMillis();
        try {
            File file = new File(target);
            if (file.exists()) {
                file.delete();
            }
            Files.copy(Paths.get(source), file.toPath());
        } finally {
            System.out.println("使用Files.copy復制文件耗時:" + (System.currentTimeMillis() - startTime) + "毫秒");
        }
    }

    public static void main(String[] args) throws IOException {
        String source = "E:/source.txt";
        String target1 = "E:/target1.txt", target2 = "E:/target2.txt", target3 = "E:/target3.txt";
        FileCopy.bioCopy(source, target1);
        FileCopy.nioCopy1(source, target2);
        FileCopy.nioCopy2(source, target3);
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM