MappedByteBuffer读取

public class MappedFileRead
{
	
	static final long G = 1024*1024*1024;
	
	private static Logger log = Logger.getLogger(MappedFileRead.class);
	
	public static void main(String[] args)
	{
		long start = - System.currentTimeMillis();
		final File file = new File("E:\\test\\test.dat");
		long length = file.length();
		int defaultThreadNum = 4;//Runtime.getRuntime().availableProcessors();
		long size = (length + defaultThreadNum - 1)/defaultThreadNum;
		if (size > G)
		{
			defaultThreadNum = (int) ((length + G -1)/ G) ;
			size = length/defaultThreadNum;
		}
		final CountDownLatch cdl = new CountDownLatch(defaultThreadNum);
		long offset = 0;
		long remain = length - offset;
		for (int threadNum = 0;threadNum < defaultThreadNum;threadNum++)
		{
			if (size > remain)
			{
				size = remain;
			}
			try
			{
				final long offsetF = offset;
				final long sizeF = size;
				new Thread(new Runnable()
				{
					
					@Override
					public void run()
					{
						MappedByteBuffer mappedByteBuffer = null;
						try
						{
							System.out.println("freeMemory = " + Runtime.getRuntime().freeMemory() + " offsetF=" + offsetF + " sizeF=" + sizeF);
							mappedByteBuffer = getMappedByteBuffer(file, MapMode.READ_ONLY, offsetF, sizeF);
							while (null == mappedByteBuffer)
							{
								try
								{
									Thread.sleep(1000);
									mappedByteBuffer = getMappedByteBuffer(file, MapMode.READ_ONLY, offsetF, sizeF);
								}
								catch (InterruptedException e)
								{
									// TODO Auto-generated catch block
									//e.printStackTrace();
								}
							}
							System.out.println("mappedByteBuffer =" + mappedByteBuffer);
							boolean isChangeLineAtLast = atLastIsChangeLine(mappedByteBuffer);
							//Charset charset = Charset.defaultCharset();
							//CharBuffer charBuffer = charset.decode(mappedByteBuffer);
							String content = byteBufferToString(mappedByteBuffer);
							System.out.println(content == null);
							LineNumberReader read = new  LineNumberReader(new StringReader(content));
							String line = read.readLine();
							while (null != line)
							{
								System.out.println(line);
								line = read.readLine();
							}
							System.out.println(Thread.currentThread().getName() + "is end!");
							
						}
						catch (IOException e)
						{
							e.printStackTrace();
						}
						finally
						{
							if (null != cdl)
							{
								cdl.countDown();
							}
							unmap(mappedByteBuffer);
						}
						
						
					}
				}).start();
				
				offset += size;
			}
			catch (Exception e)
			{
				cdl.countDown();
				e.printStackTrace();
			}
		}
		try
		{
			cdl.await();
		}
		catch (InterruptedException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//计时= 376468  
		System.out.println(	"计时= " + (System.currentTimeMillis() + start));
	}
	
	
	public static String byteBufferToString(ByteBuffer buffer) 
	{
		CharBuffer charBuffer = null;
		try 
		{
			Charset charset = Charset.defaultCharset();
			CharsetDecoder decoder = charset.newDecoder();
			charBuffer = decoder.decode(buffer);
			buffer.flip();
			return charBuffer.toString();
		} 
		catch (Exception e) 
		{
			e.printStackTrace();
			return null;
		}
	}
	
	/***
	 * 该映射区 最后一个字节 是否是换行符
	 * @param mappedByteBuffer
	 * @return
	 */
	public static boolean atLastIsChangeLine(MappedByteBuffer mappedByteBuffer)
	{
		if (null == mappedByteBuffer)
		{
			return false;
		}
		int bufferLength = mappedByteBuffer.limit();
		byte indexByte = mappedByteBuffer.get(bufferLength - 1);
		if ('\n' == indexByte)
		{
			return true;
		}
		return false;
	}
	
	/***
	 * 向映射文件写入字节
	 * @param mappedByteBuffer
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public static boolean appendData(MappedByteBuffer mappedByteBuffer,byte[] data) throws Exception
	{
		if(null == mappedByteBuffer){
			throw new Exception("mappedByteBuffer is null !");
		}
		
		mappedByteBuffer.put(data);
		flush(mappedByteBuffer);
		return true;
	}
	
	/**
	 * 强制写入到文件
	 * @param mappedByteBuffer
	 */
	private static void flush(MappedByteBuffer mappedByteBuffer)
	{
		if(null == mappedByteBuffer)
		{
			return;
		}
		mappedByteBuffer.force();
	 }
	
	/***
	 * 映射文件
	 * @param file 文件
	 * @param fileMappedMode 映射模式 
	 * @param offset 起始位置
	 * @param size 映射缓存大小
	 * @return
	 */
	public static MappedByteBuffer getMappedByteBuffer(File file,MapMode fileMappedMode,long offset,long size)
	{
		if (null == file)
		{
			log.error("file is null! ");
			return null;
		}
		
		if (size > G)
		{
			log.error("Mapped File length is to Big! ");
			return null;
		}
		
		
		if (offset < 0)
		{
			log.error("offset is less then 0");
			return null;
		}
		
		if (null == fileMappedMode)
		{
			log.error(" fileMappedMode  couldn't be null !");
			return null;
		}
		
		String randomMode = "r";
		if (fileMappedMode == MapMode.READ_WRITE|| fileMappedMode == MapMode.PRIVATE)
		{
			randomMode = "rw";
		}
		try
		{
			MappedByteBuffer map = new RandomAccessFile(file,randomMode).
					getChannel().map(fileMappedMode, offset, size);
			return map;
		}
		catch (Exception e)
		{
			// e.printStackTrace();
			log.error("getMappedByteBuffer catch Exception = [" + e.getMessage() + "]",e);
		}
		return null;
	}
	
	
	public static void unmap(final MappedByteBuffer mappedByteBuffer) {   
        if (mappedByteBuffer == null) 
        {   
            return;   
        }   
        AccessController.doPrivileged(new PrivilegedAction<Object>() 
        {   
            public Object run() {   
                try {   
                    Method getCleanerMethod = mappedByteBuffer.getClass().getMethod("cleaner", new Class[0]);   
                    if (getCleanerMethod != null) {   
                        getCleanerMethod.setAccessible(true);   
                        Object cleaner = getCleanerMethod.invoke(mappedByteBuffer, new Object[0]);   
                        Method cleanMethod = cleaner.getClass().getMethod("clean", new Class[0]);   
                        if (cleanMethod != null) {   
                            cleanMethod.invoke(cleaner, new Object[0]);   
                        }   
                    }   
                } catch (Exception e) {   
                    e.printStackTrace();   
                }   
                return null;   
            }   
    
        });   
    }  
}

<pre name="code" class="java">import java.util.StringTokenizer;

public class StringReaderUtils
{
	private StringTokenizer stringTokenizer;
	
	/**
	 * 创建一个根据分隔符 截去字符串工具
	 * @param content 字符串内容
	 * @param token 分隔符 比如换行符 或者其他标记
	 * @param isReturnToken 是否返回分隔符
	 */
	public StringReaderUtils(String content,String token,boolean isReturnToken)
	{
		stringTokenizer = new StringTokenizer(content,token,isReturnToken);
	}
	
	
	public static void main(String[] args)
	{
	}
	
	/***
	 * 读取一截 字符
	 * @return
	 */
	public String readSection()
	{
		if (stringTokenizer.hasMoreTokens() && stringTokenizer.countTokens() > 0)
		{
			return stringTokenizer.nextToken();
		}
		return null;
	}
	
	
	/***
	 * 读取一截 字符
	 * @param token 新分隔符
	 * @return
	 */
	public String readSectionByNewToken(String token)
	{
		if (stringTokenizer.hasMoreTokens() && stringTokenizer.countTokens() > 0)
		{
			return stringTokenizer.nextToken(token);
		}
		return null;
	}
	
	/**
	 * 是否还有截去字符
	 * @return
	 */
	public boolean hasMoreSection()
	{
		return stringTokenizer.hasMoreTokens();
	}
	
}


 


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值