Java IO and NIO to read large files, the speed of contrast

Topic: Assuming the machine is only 500M of memory, there is a 1.23GB of files, from one directory to another directory
Objective: To compare the efficiency of read speed IO and NIO's
details: a large file can not read the memory, otherwise it will overflow memory , each read only fixed-size data stream

Here Insert Picture Description
Be implemented in the following code, in the implementation code, the code is read all at once, some of the contents into memory, read some fixed size, look at each speed difference methods to read the file

File size 1.23GB
1. Use RandomAccessFile read the file, FileOutputStream write files, time: 8768ms
2. Use BufferedInputStream read the file, BufferedOutputStream write files, time: 2202ms
3. Use Scanner to read the file, FileOutputStream to write the file, time-consuming: 120945ms
4. use NIO, FileChannel read and write files, time:

  • NIO each read 1M, time-consuming: 8947ms
  • NIO each read 5M, time-consuming: 2976ms
  • NIO each read 10M, time-consuming: 1802ms
  • NIO each read 20M, time-consuming: 1279ms

NIO use and have substantially buffer IO-BufferedInputStream fastest read and write files, observed by a task manager in the use of memory 100M substantially fluctuate
Here Insert Picture Description

package com.zypcy.readbigfile;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Scanner;

/**
 * 读取大文件
 * 分别测试不同文件流IO与NIO读取的效率
 * 因文件很大,机器可用内存较小,无法一次读取全部内容,需要读取固定大小的数据
 * @author zhuyu
 */
public class Demo {

	public static void main(String[] args) {
		String filePath = "D:\\project\\java\\workspace\\DemoThread\\src\\com\\zypcy\\readbigfile\\bigdata.zip";
		String newPath = "D:\\project\\java\\workspace\\DemoThread\\src\\com\\zypcy\\readbigfile\\output.zip";
		
		try {
			File file = new File(filePath);
			if(!file.exists()){
				return;
			}
			File newFile = new File(newPath);
			
			//randomAccessRead(file ,newFile); 
			//测试:读取1.23GB文件耗时:8768ms
			
			//bufferedRead(file ,newFile);
			//测试:读取1.23GB文件耗时:2202ms
			
			//scannerRead(file ,newFile);
			//测试:读取1.23GB文件耗时:120945ms
			
			fileChannelRead(file ,newFile);
			//每次读取1M,耗时:8947ms
			//每次读取5M,耗时:2976ms
			//每次读取10M,耗时:1802ms
			//每次读取20M,耗时:1279ms
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 使用 RandomAccessFile 读取文件
	 * @param file
	 * @param newFile
	 */
	public static void randomAccessRead(File file , File newFile){
		//测试:读取1.23GB文件耗时:8768ms
		long d1 = System.currentTimeMillis();
		RandomAccessFile raf = null;
		OutputStream output = null;
		try {
			raf = new RandomAccessFile(file , "rw");
			output = new FileOutputStream(newFile);
			int len = 0;             //每次读取内容长度
			byte[] data = new byte[1024];//内容缓冲区
			while((len = raf.read(data)) != -1){
				output.write(data, 0, len);
			}
			long d2 = System.currentTimeMillis();
			System.out.println("randomAccessRead读取完成,耗时:" + (d2 - d1));
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			try {
				if(raf != null){
					raf.close();
				}
				if(output != null){
					output.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 使用NIO的FileChannel读取
	 * @param file
	 * @param newFile
	 */
	public static void fileChannelRead(File file , File newFile){
		//1.23GB文件
		//每次读取1M,耗时:8947ms
		//每次读取5M,耗时:2976ms
		//每次读取10M,耗时:1802ms
		//每次读取20M,耗时:1279ms
		long d1 = System.currentTimeMillis();
		FileInputStream in = null;
		FileOutputStream output = null;
		FileChannel  fic = null;
		FileChannel  foc = null;
		try {
			in = new FileInputStream(file);
			output = new FileOutputStream(newFile);
			fic = in.getChannel();
			foc = output.getChannel();
			
			//fic.transferTo(0, fic.size(), foc);
			ByteBuffer buf = ByteBuffer.allocate(20480);
			while(fic.read(buf) != -1){
				buf.flip();//切换到读取数据模式
				foc.write(buf);//将缓冲区的数据写入通道中
				buf.clear();//清空缓冲区
			}
			
			long d2 = System.currentTimeMillis();
			System.out.println("fileChannelRead读取完成,耗时:" + (d2 - d1));
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
				try {
					if(in != null){
						in.close();
					}
					if(output != null){
						output.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
	}
	
	/**
	 * 使用IO的缓冲区读取
	 * @param file
	 * @param newFile
	 */
	public static void bufferedRead(File file , File newFile){
		//测试:读取1.23GB文件耗时:2202
		long d1 = System.currentTimeMillis();
		InputStream in = null;
		OutputStream output = null;
		try {
			in = new BufferedInputStream(new FileInputStream(file)) ;
			output = new BufferedOutputStream(new FileOutputStream(newFile));
			int len = 0;
			byte[] data = new byte[1024];
			while((len = in.read(data)) != -1){
				output.write(data, 0, len);
			}
			long d2 = System.currentTimeMillis();
			System.out.println("bufferedRead读取完成,耗时:" + (d2 - d1));
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
				try {
					if(in != null){
						in.close();
					}
					if(output != null){
						output.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
	}
	
	/**
	 * 使用Scanner一行一行读取
	 * @param file
	 * @param newFile
	 */
	public static void scannerRead(File file , File newFile){
		//读取1.23GB文件耗时:120945
		long d1 = System.currentTimeMillis();
		InputStream in = null;
		OutputStream output = null;
		try {
			in = new FileInputStream(file);
			output = new FileOutputStream(newFile);
			Scanner sc = new Scanner(in, "UTF-8");
			//sc.useDelimiter("\\r\\n");
			while(sc.hasNext()){
				String content = sc.nextLine();
				output.write(content.getBytes("UTF-8"));
			}
			long d2 = System.currentTimeMillis();
			System.out.println("scannerRead读取完成,耗时:" + (d2 - d1));
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
				try {
					if(in != null){
						in.close();
					}
					if(output != null){
						output.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
	}
}

Published 273 original articles · won praise 200 · Views 1.62 million +

Guess you like

Origin blog.csdn.net/zhuyu19911016520/article/details/104411275