【Java】BufferedReader与NIO读取文件性能测试

原创
2014/01/24 13:09
阅读数 2K

说你CSV读入效率太差,是指你用的是行读方式,行读是效率比较慢的一种读法。

请问还有什么高效的读取大文件的方法吗?


我对 BufferedReader  与 NIO  读取文件效果做了一个简单的测试

测试结果:

根据测试 BufferedReader 与  NIO 读取效果是差不多的. 如果 缓存 配置不好,则NIO效果比BufferedReader慢。


package test.com.linapex.nio;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * 项目名称:LinApex-Student 	<br><br>
 * 
 * 类名称:TNIO 		<br><br>
 * 
 * 创建人:LinApex@163.com 	<br><br>
 * 
 * 创建时间:2014-1-24 下午12:13:41 	<br><br>
 * 
 * 版本:1.0					<br><br>
 * 
 * 功能描述:
 */
public class TNIO
{

	public static void doBufferReadFile(File file) throws Exception
	{
		BufferedReader reader = null;
		try
		{
			reader = new BufferedReader(new FileReader(file));
			String str = null;

			int num = 0;
			while ((str = reader.readLine()) != null)
			{
				num++;
			}
		} finally
		{
			reader.close();
		}
	}

	public static void doNioReadFile(File file) throws Exception
	{
		String enterStr = "\n";

		FileChannel inChannel = new FileInputStream(file).getChannel();
		ByteBuffer buffer = ByteBuffer.allocate(BSIZE);

		StringBuilder newlinesBui = new StringBuilder();
		while (inChannel.read(buffer) != -1)
		{
			buffer.flip();

			//数据组合.
			String content = new String(buffer.array());
			newlinesBui.append(content).toString();

			int fromIndex = 0;
			int endIndex = -1;
			//循环找到 \n
			while ((endIndex = newlinesBui.indexOf(enterStr, fromIndex)) > -1)
			{
				//得到一行
				String line = newlinesBui.substring(fromIndex, endIndex);
				//				System.out.print(line);

				fromIndex = endIndex + 1;
			}

			newlinesBui.delete(0, fromIndex);
			buffer.clear();
		}

	}

	final static int BSIZE = 1024 * 1024;

	public static void main(String[] args) throws Exception
	{
		long begin = System.currentTimeMillis();
		File csvFile = new File("D:\\baiduyundownload\\test\\2000W\\1-200W.csv");

		doNioReadFile(csvFile);
		//		bufferRead(csvFile);

		long end = System.currentTimeMillis();
		System.out.println(end - begin);
	}
}

NIO(缓冲1M)测试三次结果如下:

2418

2390

2370


BufferReader测试三次结果如下:

2547

2524

2535


NIO(缓冲1024字节,将 BSIZE 改成 1024 )测试三次结果如下:

3366

3318

3372




展开阅读全文
打赏
1
0 收藏
分享
加载中
newlinesBui.append(content).toString();
为什么这里加上toString 性能反而好很多?
2014/03/10 15:02
回复
举报
linapex博主

引用来自“哈库纳”的评论

行读性能上优化的余地已经不大了,除非你有更有效的办法定位要读取的块大小。
无论怎么读一定要带上 Buffer,这个才是重要的。

是的。 JDK5.0之后,对IO都已经优化过了,底层都采用 NIO。
2014/01/24 16:37
回复
举报
行读性能上优化的余地已经不大了,除非你有更有效的办法定位要读取的块大小。
无论怎么读一定要带上 Buffer,这个才是重要的。
2014/01/24 16:25
回复
举报
更多评论
打赏
3 评论
0 收藏
1
分享
返回顶部
顶部