NIO读取日志文件

在分布式开发中对日志处理的一些简单思路

一.约定日志的格式,以及生成规则

1.约定日志的输出格式

2.约定生成日志的目录

3.约定日志生成的时段,是按天生成一个日志文件、还是按小时生成

 

二.日志抽取

1.日志抽取的应用对日志信息抽取入mysql库

2.定时统计各个应用所要统计的内容(srping+quarz)

3.提供web端可以查看统计分析(HightChar)

 

 文件的收集整理,对日志的IO读取写了简单的测试方法:

 

 

@Test
	public  void test() throws Exception{
		
        long time = System.currentTimeMillis();
        System.out.println("开始时间"+time);
        
	RandomAccessFile fin = new RandomAccessFile("D:\\logs\\catalina.out", "r");
	RandomAccessFile fout = new RandomAccessFile("D:\\logs\\catalina.out1", "rw");
        FileChannel fcin = fin.getChannel();  
        FileChannel fcout = fout.getChannel();  
        ByteBuffer buffer = ByteBuffer.allocate(15360);  
        int byteRead = 0;
        while((byteRead=fcin.read(buffer))>0){
        	buffer.flip();
        	while(buffer.hasRemaining()){
        		 fcout.write(buffer);
	   		}
           buffer.clear();
        }
        fcin.close();  
        fcout.close();  
        fin.close();  
        fout.close();  
        System.out.println("结束时间"+System.currentTimeMillis());
        System.out.println("消耗时间" +(System.currentTimeMillis() - time));
	}

 

 

    本机的配置是win7 4G内存  64为系统  32为jdk

 

    采用的NIO来处理,此日志为 2.57 GB (2,764,091,431 字节)读取使用以上ByteBuffer.allocate(15360);         得到的值是

 

开始时间1419939751750
结束时间1419939811927
消耗时间60177

    这个值的的设定可根据自己的电脑实际配置测试得到,这个值在我电脑上读取几乎感觉不到cpu的波动,这个开多个线程处理也是可行的。

 

     文件搜集完后那就是对文件的读取,并入数据库,采用的测试方法是:

	@Test
	public  void testRead() throws Exception{
        long time = System.currentTimeMillis();
        System.out.println("开始时间"+time);
	RandomAccessFile fin = new RandomAccessFile("D:\\logs\\logger.log", "r");
	long pos = 0;
        fin.seek(pos);
		String line = null;
		while((line=fin.readLine())!=null){
			pos = fin.getFilePointer();
			System.out.println(line + "-----" + fin.getFilePointer());
			if(pos==232){
				break;
			}
		}
		fin.seek(pos);
		while((line=fin.readLine())!=null){
			System.out.println(line + "-----" + fin.getFilePointer());
		}
        System.out.println("结束时间"+System.currentTimeMillis());
        System.out.println("消耗时间" +(System.currentTimeMillis() - time));
	}

 

这个类可以设置已经读到位置,下次从设定的位置开始读取  pos = fin.getFilePointer(),逐行读取解析入库

 

还有NIO种另外一种文件写入方式

	@Test
	public void testTransTo(){
	try{
		
        long time = System.currentTimeMillis();
        System.out.println("开始时间"+time);
		
	RandomAccessFile fromFile = new RandomAccessFile("D:\\logs\\catalina.out", "r");
	FileChannel      fromChannel = fromFile.getChannel(); 
		
	RandomAccessFile toFile = new RandomAccessFile("D:\\logs\\catalina.out1", "rw"); 
	FileChannel      toChannel = toFile.getChannel(); 
		
	long position = 0;
	long persize = fromChannel.size(); 
	long maxSize = persize;
		
	//FileChannel的transferFrom()方法可以将数据从源通道传输到FileChannel中
	//toChannel.transferFrom(fromChannel, position, count);
		
	//transferTo()方法将数据从FileChannel传输到其他的channel中。下面是一个简单的例子: 适合读取小文件的小于1G的在30毫秒可处理完, 读取大文件瞬间cpu暴增,如果执行多个可导致内存溢出
		
	fromChannel.transferTo(position, persize, toChannel);
		
	fromFile.close();
	fromChannel.close();
	toFile.close();
	toChannel.close();
        
        System.out.println("结束时间"+System.currentTimeMillis());
        System.out.println("消耗时间" +(System.currentTimeMillis() - time)/1000);
		
	}catch(Exception e){
	    e.printStackTrace();
	}
}

 

这种方式读取2.5个的log日志我的cpu瞬间达到90%以上,但读取时间是47,缩减为原来的1/2需要24但cpu也是瞬间到达90%以上,缩减为原来的1/3的读取时间为17 cpu比较稳定,所以才想是不是在读取1G一下的日志时速度回高一些。

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(nio)