Scanner和BufferedReader读取文件速度比较

来源:互联网 发布:linux sleep函数实现 编辑:程序博客网 时间:2024/06/05 21:52

测试结果是BufferedReader快10倍还不止,测试过程中遇到一个有趣的问题,BufferedReader读到文件尾后,怎么从头开始读取?按网上找到的资料,java提供了mark(int readAheadLimit) 和reset()配合来回到起始位置。但按网上提供的方法始终报异常,注意代码中mark传入的参数是文件长度:

 try {            File file = new File("D:/Test.java");            BufferedReader reader = new BufferedReader(new FileReader(file));            String content=reader.readLine();            reader.mark((int)file.length());            while(content!=null){                System.out.println(content);                content=reader.readLine();            }            reader.reset();            content=reader.readLine();            while(content!=null){                System.out.println(content);                content=reader.readLine();            }        } catch (FileNotFoundException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }
Exception in thread "main" java.io.IOException: Mark invalid    at java.io.BufferedReader.reset(BufferedReader.java:512)    at ComScannerAndBuff.init(ComScannerAndBuff.java:63)    at ComScannerAndBuff.main(ComScannerAndBuff.java:8)

回去看了下java源码,是这样注释mark方法的,关于参数readAheadLimit有说明,如果超出readAheadLimit的长度后调用reset将引起失败。因为最后reader.readLine()读到了null,所以文件流指针可能已经超出了文件的长度;于是,把mark的参数设置成file.length() + 1,问题解决。具体看我的代码吧。

    /**     * Marks the present position in the stream.  Subsequent calls to reset()     * will attempt to reposition the stream to this point.  Not all     * character-input streams support the mark() operation.     *     * @param  readAheadLimit  Limit on the number of characters that may be     *                         read while still preserving the mark.  After     *                         reading this many characters, attempting to     *                         reset the stream may fail.     *     * @exception  IOException  If the stream does not support mark(),     *                          or if some other I/O error occurs     */
import java.io.*;import java.util.*;public class ComScannerAndBuff {    public static void main(String args[]) throws IOException {        //Scanner读取文件        long startTime = System.currentTimeMillis();        init(new File("./shadowsocks.log"));        long endTime = System.currentTimeMillis();        long size = new File("./测试文本文件.txt").length();        System.out.printf("拷贝%dM文件耗时:%d\n" , size / 1000 / 1000, (endTime - startTime) / 1000);        // compare("./测试文本文件.txt");    }    private static void compare(String filename) throws IOException{        long startTime, endTime;        //Scanner读取文件        startTime = System.currentTimeMillis();        readByScanner(new File(filename));        endTime = System.currentTimeMillis();        long scannerTime = endTime - startTime;        //缓冲流读取文件        startTime = System.currentTimeMillis();        readByBuffer(new File(filename));        endTime = System.currentTimeMillis();        long buffeTime = endTime - startTime;        System.out.println("scanner 读取文件耗时:" + scannerTime / 1000);        System.out.println("buffered读取文件耗时:" + buffeTime / 1000);    }    private static void readByBuffer(File file) throws IOException {        BufferedReader br = null;        br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));        for( ; ; ) {            String string = br.readLine();            if(string == null) {                break;            }        }    }    private static void readByScanner(File file) throws IOException {        Scanner scanner = null;        scanner = new Scanner(new FileInputStream(file));        while(scanner.hasNext()) {            String string = scanner.nextLine();        }    }    //利用一份6M大小的日志文件生成一份500M的文件用来做测试    private static void init(File file) throws IOException {        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));        //追加的方式输出        FileWriter fw = new FileWriter("./测试文本文件.txt");        for(int i = 0; i < 100; i++ ) {            br.mark(((int)file.length() + 1));            for( ; ; ) {                String string = br.readLine();                if(string == null) {                    br.reset();                    break;                }                fw.write(string);                fw.write("\n");            }        }    }}
0 0