本博客属原创文章,欢迎转载!转载请务必注明出处:http://guoyunsky.iteye.com/blog/854730
欢迎加入Heritrix群(QQ): 109148319 , 10447185 , Lucene/Solr群(QQ) : 118972724
慢慢的得开始考虑些底层的东西,以前微乎其微的一个小功能或许在今天就足已影响你程序的性能、效率等问题.就如现在碰到的,将一个Byte数组,转换成字符串,并且还可以动态的根据位置获取该位置的字符.如果在以往,可能简单的借用String几个方法就行.但换到今天,不得不考虑效率的问题. 这是我总结出来的一个转换类,也参考了开源机器爬虫Heritrix,主要借用Java的NIO来实现.代码和测试类如下:
import java.io.Closeable; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import org.archive.io.CharSubSequence; /** * @contributor guoyun */ public class ByteArrayToCharBufferAndString implements CharSequence,Closeable{ private CharBuffer charBuffer=null; public static final String DEFAULT_ENCODING="ISO8859_1"; /** * @param buffer byte数组 * @param start 开始位置 * @param size 长度 * @param encoding 编码 */ public ByteArrayToCharBufferAndString(byte[] buffer,long start,long size,String encoding){ super(); charBuffer=byteArrayToCharBuffer(buffer,start,size,encoding); } private CharBuffer byteArrayToCharBuffer(byte[] buffer,long start,long size,String encoding){ ByteBuffer bb=ByteBuffer.wrap(buffer); bb.position((int)start); bb.limit((int)size); Charset charset=null; try { charset=Charset.forName(encoding); } catch (RuntimeException e) { charset=Charset.forName(DEFAULT_ENCODING); } return charset.decode(bb).asReadOnlyBuffer(); } @Override public char charAt(int index) { return this.charBuffer==null?null:this.charBuffer.charAt(index); } @Override public int length() { return this.charBuffer==null?0:this.charBuffer.limit(); } @Override public CharSequence subSequence(int start, int end) { return new CharSubSequence(this, start, end); } @Override public void close() { if(this.charBuffer!=null){ this.charBuffer.clear(); this.charBuffer=null; } } @Override public String toString() { StringBuffer sb = new StringBuffer(length()); sb.append(this); return sb.toString(); } /** * @param args * @throws UnsupportedEncodingException */ public static void main(String[] args) throws UnsupportedEncodingException { //String str="123456789abcdefghijklmnopqrstuvwxyz"; String str="我宣布,中华人民共和国,成立了!中华人民共和国,从此站起来了!"; byte[] buffer=str.getBytes("UTF-8"); ByteArrayToCharBufferAndString test=null; try { test=new ByteArrayToCharBufferAndString(buffer,0,buffer.length,"UTF-8"); System.out.println("转换成String:"+test.toString()); System.out.println("长度:"+test.length()); System.out.println("获取字符,位置5:"+test.charAt(5)+",位置15:"+test.charAt(15)); } catch (Exception e) { e.printStackTrace(); }finally{ if(test!=null){ test.close(); } } } }
补充:本类只适用于与多线程IO操作环境下.如获取某个端口数据(传统的Socket请求响应)、IO.对于非以上环境这个类反而如有朋友说的那样,反而是浪费了.之前提到说借用NIO,所以没做这个说明.
这里借用网络爬虫打一个比方.爬虫一般一个URL对应一个线程去获取该URL资源.每个URL都从服务器的响应流里面读取字节到以上的byte数组.如果不采用NIO,则线程会一直等在读取字节流上面,影响性能.同时,每读取完一次byte数组就转换成String,则会产生垃圾,转换的String对象不能循环利用(String是final类型).所以以上这个类的作用就出来了,获取服务器响应字节流的时候,没有了线程等待.同时对获取到了的数据用该类包装后,该类对象还可以循环利用.
我也刚刚见识NIO的作用,对于底层也没多少经验.欢迎大家指教!很感谢!
更多技术文章、感悟、分享、勾搭,请用微信扫描:
相关推荐
易语言十六进制与字符串转换源码,十六进制与字符串转换,字符串到十六进制线程,十六进制到字符串线程
Java数组 Java环境配置 Java多线程编程 分别为三个PDF文件
自定义byte数组,可变长度,轻量高效,解决集合存储简单数据的包装问题,自增缓存减少运算,方便多次调用,非线程同步
一个java 多线程操作数据库应用程序!!!
java线程+java IO流操作以及多线程的处理
Java多线程.drawio
VC多线程实现数组排序VC多线程实现数组排序VC多线程实现数组排序VC多线程实现数组排序VC多线程实现数组排序
1:本程序读取二进制文件,并把读到的二进制文件保存为文本数据 2:二进制文件内容一系列的...3:本程序采用了多线程技术,读取二进制文件时,界面不会卡顿 4:实例二进制文件为data.dat.默认的文本保存地址为c盘根目录
JVM从外部数据源中读入或写出数据,称为流 JVM从外部数据源中读入数据,称输入流 JVM从内存中写出数据,称为输出流 java.io包中都是流用到的类
Java线程:概念与原理 2 一、操作系统中线程和进程的概念 2 二、Java中的线程 3 三、Java中关于线程的名词解释 3 四、线程的状态转换和生命周期 4 Java线程:创建与启动 7 Java线程:线程名称的设定及获取 10 Java...
NULL 博文链接:https://toknowme.iteye.com/blog/2212529
java多线程并发查询数据库,使用线程池控制分页,并发查询。
java多线程处理数据库数据,使用并发包,无框架,可批量处数据库数据,进行增删改。。等等操作。
自己写的 io流 多线程 实现上传下载 小程序 java
该对象并不是流体系中的一员,其封装了字节流,同时还封装了一个缓冲区(字符数组),通过内部的指针来操作字符数组中的数据。 该对象特点: 该对象只能操作文件,所以构造函数接收两种类型的参数:a.字符串文件...
用java平台利用java的多线程特点,编写进度条的现实以及当前时间的实时更新。
java基础之多线程的练习题,博客访问地址: http://blog.csdn.net/u014028392/article/details/76906801
Java二进制IO类与文件复制操作实例,好像是一本书的例子,源代码有的是独立运行的,与同目录下的其它代码文件互不联系,这些代码面向初级、中级Java程序员。 Java访问权限控制源代码 1个目标文件 摘要:Java源码...
JAVA多线程实验,字符移动、小球碰撞两个实验来说明JAVA的多线程
C#语言编写使用HTTP读取网络资源至byte数组;注意读取时会阻塞,需要放到线程里。