Java讀取文件的幾種方式


package com.mesopotamia.test;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Scanner;

import org.apache.log4j.Logger;
/*
 * 原文學習請加微信訂閱號:it_pupil
 * **/
public class FileRead {
	private static Logger logger = Logger.getLogger(FileRead.class); 
	public static void main(String args[]) throws FileNotFoundException{
		String path = "C:" + File.separator + "test" + File.separator + "Alice.txt";  
		readFile3(path);
	}
	
	public static void readFile(String path) throws FileNotFoundException {
		long start = System.currentTimeMillis();//開始時間
		int bufSize = 1024;//1K緩沖區
		File fin = new File(path); 
		/*
		 * 通道就是為操作文件而建立的一個連接。(讀寫文件、內存映射等)
		 * 此處的getChannel()可以獲取通道;
		 * 用FileChannel.open(filename)也可以創建一個通道。
		 * "r"表示只讀。
		 * 
		 * RandomAccessFile是獨立與I/O流家族的類,其父類是Object。
		 * 該類因為有個指針可以挪動,所以,可以從任意位置開始讀取文件數據。
		 * **/
		FileChannel fcin = new RandomAccessFile(fin, "r").getChannel();
		//給字節緩沖區分配大小
		ByteBuffer rBuffer = ByteBuffer.allocate(bufSize);						
		String enterStr = "\n";
		try {
			byte[] bs = new byte[bufSize];
			String tempString = null;
			while (fcin.read(rBuffer) != -1) {//每次讀1k到緩沖區
				int rSize = rBuffer.position();//記錄緩沖區當前位置
				rBuffer.rewind();//位置歸零,標記取消,方便下次循環重新讀入緩沖區。
				rBuffer.get(bs);//將緩沖區數據讀到字節數組中
				rBuffer.clear();//清除緩沖
				/*
				 * 用默認編碼將指定字節數組的數據構造成一個字符串
				 * bs:指定的字節數組,0:數組起始位置;rSize:數組結束位置
				 * */
				tempString = new String(bs, 0, rSize);
				int fromIndex = 0;//每次讀的開始位置
				int endIndex = 0;//每次讀的結束位置
				//按行讀String數據
				while ((endIndex = tempString.indexOf(enterStr, fromIndex)) != -1) {
					String line = tempString.substring(fromIndex, endIndex);//轉換一行			
					System.out.print(line);					 
					fromIndex = endIndex + 1;
				}
			}
            long end = System.currentTimeMillis();//結束時間
            System.out.println("傳統IO讀取數據,指定緩沖區大小,總共耗時:"+(end - start)+"ms");

		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static void readFile1(String path) { 
    	long start = System.currentTimeMillis();//開始時間
        File file = new File(path);  
        if (file.isFile()) {  
        	/*使用Reader家族,表示我要讀字符數據了,
        	 *使用該家族中的BufferedReader,表示我要建立緩沖區讀字符數據了。
        	 * */
            BufferedReader bufferedReader = null;  
            FileReader fileReader = null;  
            try {  
                fileReader = new FileReader(file); 
                //嵌套使用,裝飾者模式,老生常談。裝飾者模式的使用,可以讀前面小磚寫的《從熏肉大餅到裝飾者模式》
                bufferedReader = new BufferedReader(fileReader);  
                String line = bufferedReader.readLine();  
                //一行一行讀
                while (line != null) { //按行讀數據
                    System.out.println(line);  
                    line = bufferedReader.readLine();  
                }  
            } catch (FileNotFoundException e) {  
                e.printStackTrace();  
            } catch (IOException e) {  
                e.printStackTrace();  
            } finally {  
            	//最后一定要關閉
                try {  
                    fileReader.close();  
                    bufferedReader.close();  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
                long end = System.currentTimeMillis();//結束時間
                System.out.println("傳統IO讀取數據,不指定緩沖區大小,總共耗時:"+(end - start)+"ms");
            }  
  
        }  
    } 
	
	public static void readFile3(String path) {
		long start = System.currentTimeMillis();//開始時間
        long fileLength = 0;  
        final int BUFFER_SIZE = 0x300000;// 3M的緩沖  
            File file = new File(path);  
            fileLength = file.length();  
            try {  
            	/*使用FileChannel.map方法直接把整個fileLength大小的文件映射到內存中**/
                MappedByteBuffer inputBuffer = new RandomAccessFile(file, "r").getChannel()
                	.map(FileChannel.MapMode.READ_ONLY, 0, fileLength);// 讀取大文件  
                byte[] dst = new byte[BUFFER_SIZE];// 每次讀出3M的內容
                //每3M做一個循環,分段將inputBuffer的數據取出。
                for (int offset = 0; offset < fileLength; offset += BUFFER_SIZE) {
                	//防止最后一段不夠3M
                    if (fileLength - offset >= BUFFER_SIZE) {
                    	//一個字節一個字節的取出來放到byte[]數組中。
                        for (int i = 0; i < BUFFER_SIZE; i++)  
                            dst[i] = inputBuffer.get(offset + i);  
                    } else {  
                        for (int i = 0; i < fileLength - offset; i++)  
                            dst[i] = inputBuffer.get(offset + i);  
                    }  
                    // 將得到的3M內容給Scanner,這里的XXX是指Scanner解析的分隔符。
                    Scanner scan = new Scanner(new ByteArrayInputStream(dst)).useDelimiter("XXX");  
                    //hasNext()所參照的token就是上面的XXX
                    while (scan.hasNext()) {  
                        // 這里為對讀取文本解析的方法  
                        System.out.print(scan.next() + "XXX");  
                    }  
                    scan.close();  
                }  
                System.out.println();
                long end = System.currentTimeMillis();//結束時間
                System.out.println("NIO 內存映射讀大文件,總共耗時:"+(end - start)+"ms");
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
    } 
}

  


免責聲明!

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



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