java NIO学习之处理速度比较

本文通过对比实验展示了在Java中,使用普通数据流、NIO缓冲区和NIO文件映射到内存进行文件读写操作的性能差异。实验结果显示,NIO缓冲区在写入性能上显著优于普通流,而内存映射在读取时表现出优势,但写入速度相对较慢。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里像文件写入500000个数字,并且读出,使用普通的数据流读写,NIO流读写和NIO流文件映射到内存读写三种方式相互比较:

package inputoutputStream;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

public class NIO {

	private ByteBuffer b;
	private final static String INPUT="C:\\Users\\samsung\\Desktop\\h.txt";
	private final static String OUTPUT1="C:\\Users\\samsung\\Desktop\\output1.txt";
	private final static String OUTPUT2="C:\\Users\\samsung\\Desktop\\output2.txt";
	private final static String OUTPUT3="C:\\Users\\samsung\\Desktop\\output3.txt";
	private final static int max=500000;
	
	public NIO(){
		b=ByteBuffer.allocate(max*4);
	}
	
	public NIO(int capacity){
		b=ByteBuffer.allocate(capacity);
	}
	
	public void buffer(){
		for(int i=0;i<10;i++){
			b.put((byte)i);
		}
		b.flip();
		while (b.hasRemaining()) {
			System.out.println(b.get());
		}
	}
	
	public void nioCopyFile()throws Exception{
		FileInputStream in=new FileInputStream(new File(INPUT));
		FileOutputStream out =new FileOutputStream(new File(OUTPUT1));
		FileChannel reader=in.getChannel();
		FileChannel writer=out.getChannel();
		int length=0;
		while((length=reader.read(b))!=-1){
			b.flip();
			writer.write(b);
			b.clear();
		}
		reader.close();
		writer.close();
		System.out.println("copy over~~~");
	}
	
	public void compareSpeed() throws Exception{
		long start1=System.currentTimeMillis();
		streamWrite();
		long end1=System.currentTimeMillis();
		long start2=System.currentTimeMillis();
		streamRead();
		long end2=System.currentTimeMillis();
		long start3=System.currentTimeMillis();
		bufferWrite();
		long end3=System.currentTimeMillis();
		long start4=System.currentTimeMillis();
		bufferRead();
		long end4=System.currentTimeMillis();
		long start5=System.currentTimeMillis();
		mapWrite();
		long end5=System.currentTimeMillis();
		long start6=System.currentTimeMillis();
		mapRead();
		long end6=System.currentTimeMillis();
		System.out.println("stream write:"+(end1-start1)+"ms   stream read:"+(end2-start2)+"ms");
		System.out.println("buffer write:"+(end3-start3)+"ms   buffer read:"+(end4-start4)+"ms");
		System.out.println("map write:   "+(end5-start5)+"ms   map read:   "+(end6-start6)+"ms");
	}
	
	public void streamWrite() throws IOException{
		File file=new File(OUTPUT1);
		DataOutputStream outputStream=new DataOutputStream(new FileOutputStream(file,false));
		for(int i=0;i<max;i++){
			outputStream.writeInt(i);
		}
		outputStream.close();
	}
	
	public void streamRead() throws IOException{
		File file=new File(OUTPUT1);
		DataInputStream inputStream=new DataInputStream(new FileInputStream(file));
		for(int i=0;i<max;i++){
			System.out.println("stream:"+inputStream.readInt());;
		}
		inputStream.close();
	}
	
	public void bufferWrite() throws IOException{
		File file=new File(OUTPUT2);
		FileOutputStream out=new FileOutputStream(file,false);
		FileChannel write=out.getChannel();
		for(int i=0;i<max;i++){
			b.put(intToByte(i));
		}
		b.flip();
		write.write(b);
		write.close();
	}
	
	public void bufferRead() throws IOException{
		File file=new File(OUTPUT2);
		FileInputStream in=new FileInputStream(file);
		FileChannel reader=in.getChannel();
		reader.read(b);
		b.flip();
		for(int i=0;i<max;i++){
			System.out.println("buffer:"+ByteToInt(b.get(), b.get(), b.get(), b.get()));
		}
		reader.close();
	}
	/*
	 * 注意这里使用FileOutputStream就只能是可写,不可读,会报异常onReadableChannelException
	 * FileOutputStream 生成的FileChannel只能写入,并且一旦建立这个对象,则与之关联的文件内容被清空.
	 * FileInputStream 生成的FileChannel是只读的,尝试写入是抛异常:NonWritableChannelException
	 * 由RandomAccessFile获取的FileChannel则仍旧可读可写.
	 */
	public void mapWrite() throws IOException{
		File file=new File(OUTPUT3);
		//FileOutputStream outputStream=new FileOutputStream(file,false);
		RandomAccessFile randomFile=new RandomAccessFile(file, "rw");
		FileChannel write=randomFile.getChannel();
		//IntBuffer buffer=write.map(FileChannel.MapMode.READ_WRITE, 0, max*4).asIntBuffer();
		MappedByteBuffer buffer=write.map(FileChannel.MapMode.READ_WRITE, 0, max*4);
		for(int i=0;i<max;i++){
			buffer.put(intToByte(i));
		}
		write.close();
	}
	
	public void mapRead() throws IOException{
		File file=new File(OUTPUT3);
		FileInputStream inputStream=new FileInputStream(file);
		FileChannel read=inputStream.getChannel();
		//IntBuffer buffer=read.map(FileChannel.MapMode.READ_ONLY, 0, read.size()).asIntBuffer();
		MappedByteBuffer buffer=read.map(FileChannel.MapMode.READ_ONLY, 0, read.size());
		for(int i=0;i<max;i++){
			//System.out.println("buffer:"+buffer.get());
			System.out.println("map:"+ByteToInt(buffer.get(), buffer.get(), buffer.get(), buffer.get()));
		}
		read.close();
	}
	public byte[] intToByte(int i){
		byte target[]=new byte[4];
		target[3]=(byte)(i & 0xff);
		target[2]=(byte)((i>>8) & 0xff);
		target[1]=(byte)((i>>16) & 0xff);
		target[0]=(byte)((i>>24) & 0xff);
		return target;
	}
	
	public int ByteToInt(byte b1,byte b2,byte b3,byte b4){
		return ((b1 & 0xff)<<24)|((b2 & 0xff)<<16)|((b3 & 0xff)<<8)|(b4 & 0xff);
	}
	
	public static void main(String[] args)throws Exception {
		NIO io=new NIO();
	//	io.buffer();
	//	io.nioCopyFile();
		io.compareSpeed();
	}
}
比较结果:

stream write:6344ms   stream read:7193ms
buffer write:30ms   buffer read:5998ms
map write:   60ms   map read:   4703ms

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值