仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 452|回复: 7
打印 上一主题 下一主题

[学习教程] 了解下JAVA的java io进修(十一) 缓冲输出流的认知、源码和示例

[复制链接]
再见西城 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-18 11:00:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
在ruby里才是一切皆对象。当然我不并不是很了解ruby,但是ruby确实是将语法简化得很好。
BufferedInputStream(缓冲输出流)的认知、源码和示例
本章内容包含3个部分:BufferedInputStream先容,BufferedInputStream源码,和BufferedInputStream利用示例。
BufferedInputStream先容
BufferedInputStream是缓冲输出流。它承继于FilterInputStream。
BufferedInputStream的感化是为另外一个输出流增加一些功效,比方,供应“缓冲功效”和撑持“mark()标志”和“reset()重置办法”。
BufferedInputStream实质上是经由过程一个外部缓冲区数组完成的。比方,在新建某输出流对应的BufferedInputStream后,当我们经由过程read()读取输出流的数据时,BufferedInputStream会将该输出流的数据分批的填进到缓冲区中。每当缓冲区中的数据被读完以后,输出流会再次添补数据缓冲区;云云重复,直到我们读完输出流数据地位。
BufferedInputStream函数列表
  1. BufferedInputStream(InputStreamin)
  2. BufferedInputStream(InputStreamin,intsize)
  3. synchronizedintavailable()
  4. voidclose()
  5. synchronizedvoidmark(intreadlimit)
  6. booleanmarkSupported()
  7. synchronizedintread()
  8. synchronizedintread(byte[]buffer,intoffset,intbyteCount)
  9. synchronizedvoidreset()
  10. synchronizedlongskip(longbyteCount)
复制代码
BufferedInputStream源码剖析(基于jdk1.7.40)
  1. packagejava.io;
  2. importjava.util.concurrent.atomic.AtomicReferenceFieldUpdater;
  3. publicclassBufferedInputStreamextendsFilterInputStream{
  4. //默许的缓冲巨细是8192字节
  5. //BufferedInputStream会依据“缓冲区巨细”来逐次的添补缓冲区;
  6. //即,BufferedInputStream添补缓冲区,用户读取缓冲区,读完以后,BufferedInputStream会再次添补缓冲区。云云轮回,直到读完数据...
  7. privatestaticintdefaultBufferSize=8192;
  8. //缓冲数组
  9. protectedvolatilebytebuf[];
  10. //缓存数组的原子更新器。
  11. //该成员变量与buf数组的volatile关头字配合构成了buf数组的原子更新功效完成,
  12. //即,在多线程中操纵BufferedInputStream对象时,buf和bufUpdater都具有原子性(分歧的线程会见到的数据都是不异的)
  13. privatestaticfinal
  14. AtomicReferenceFieldUpdater<BufferedInputStream,byte[]>bufUpdater=
  15. AtomicReferenceFieldUpdater.newUpdater
  16. (BufferedInputStream.class,byte[].class,"buf");
  17. //以后缓冲区的无效字节数。
  18. //注重,这里是指缓冲区的无效字节数,而不是输出流中的无效字节数。
  19. protectedintcount;
  20. //以后缓冲区的地位索引
  21. //注重,这里是指缓冲区的地位索引,而不是输出流中的地位索引。
  22. protectedintpos;
  23. //以后缓冲区的标志地位
  24. //markpos和reset()共同利用才成心义。操纵步骤:
  25. //(01)经由过程mark()函数,保留pos的值到markpos中。
  26. //(02)经由过程reset()函数,会将pos的值重置为markpos。接着经由过程read()读取数据时,就会从mark()保留的地位入手下手读取。
  27. protectedintmarkpos=-1;
  28. //marklimit是标志的最年夜值。
  29.         //检察本栏目更多出色内容:http://www.bianceng.cn/Programming/Java/
  30. //关于marklimit的道理,我们在前面的fill()函数剖析中会具体申明。这对了解BufferedInputStream相称主要。
  31. protectedintmarklimit;
  32. //猎取输出流
  33. privateInputStreamgetInIfOpen()throwsIOException{
  34. InputStreaminput=in;
  35. if(input==null)
  36. thrownewIOException("Streamclosed");
  37. returninput;
  38. }
  39. //猎取缓冲
  40. privatebyte[]getBufIfOpen()throwsIOException{
  41. byte[]buffer=buf;
  42. if(buffer==null)
  43. thrownewIOException("Streamclosed");
  44. returnbuffer;
  45. }
  46. //机关函数:新建一个缓冲区巨细为8192的BufferedInputStream
  47. publicBufferedInputStream(InputStreamin){
  48. this(in,defaultBufferSize);
  49. }
  50. //机关函数:新建指定缓冲区巨细的BufferedInputStream
  51. publicBufferedInputStream(InputStreamin,intsize){
  52. super(in);
  53. if(size<=0){
  54. thrownewIllegalArgumentException("Buffersize<=0");
  55. }
  56. buf=newbyte[size];
  57. }
  58. //从“输出流”中读取数据,并添补到缓冲区中。
  59. //前面会对该函数举行具体申明!
  60. privatevoidfill()throwsIOException{
  61. byte[]buffer=getBufIfOpen();
  62. if(markpos<0)
  63. pos=0;/*nomark:throwawaythebuffer*/
  64. elseif(pos>=buffer.length)/*noroomleftinbuffer*/
  65. if(markpos>0){/*canthrowawayearlypartofthebuffer*/
  66. intsz=pos-markpos;
  67. System.arraycopy(buffer,markpos,buffer,0,sz);
  68. pos=sz;
  69. markpos=0;
  70. }elseif(buffer.length>=marklimit){
  71. markpos=-1;/*buffergottoobig,invalidatemark*/
  72. pos=0;/*dropbuffercontents*/
  73. }else{/*growbuffer*/
  74. intnsz=pos*2;
  75. if(nsz>marklimit)
  76. nsz=marklimit;
  77. bytenbuf[]=newbyte[nsz];
  78. System.arraycopy(buffer,0,nbuf,0,pos);
  79. if(!bufUpdater.compareAndSet(this,buffer,nbuf)){
  80. thrownewIOException("Streamclosed");
  81. }
  82. buffer=nbuf;
  83. }
  84. count=pos;
  85. intn=getInIfOpen().read(buffer,pos,buffer.length-pos);
  86. if(n>0)
  87. count=n+pos;
  88. }
  89. //读取下一个字节
  90. publicsynchronizedintread()throwsIOException{
  91. //若已读完缓冲区中的数据,则挪用fill()从输出流读取下一部分数据来添补缓冲区
  92. if(pos>=count){
  93. fill();
  94. if(pos>=count)
  95. return-1;
  96. }
  97. //从缓冲区中读取指定的字节
  98. returngetBufIfOpen()[pos++]&0xff;
  99. }
  100. //将缓冲区中的数据写进到字节数组b中。off是字节数组b的肇端地位,len是写进长度
  101. privateintread1(byte[]b,intoff,intlen)throwsIOException{
  102. intavail=count-pos;
  103. if(avail<=0){
  104. //减速机制。
  105. //假如读取的长度年夜于缓冲区的长度而且没有markpos,
  106. //则间接从原始输出流中举行读取,从而制止无谓的COPY(从原始输出流至缓冲区,读取缓冲区全体数据,清空缓冲区,
  107. //从头填进原始输出流数据)
  108. if(len>=getBufIfOpen().length&&markpos<0){
  109. returngetInIfOpen().read(b,off,len);
  110. }
  111. //若已读完缓冲区中的数据,则挪用fill()从输出流读取下一部分数据来添补缓冲区
  112. fill();
  113. avail=count-pos;
  114. if(avail<=0)return-1;
  115. }
  116. intcnt=(avail<len)?avail:len;
  117. System.arraycopy(getBufIfOpen(),pos,b,off,cnt);
  118. pos+=cnt;
  119. returncnt;
  120. }
  121. //将缓冲区中的数据写进到字节数组b中。off是字节数组b的肇端地位,len是写进长度
  122. publicsynchronizedintread(byteb[],intoff,intlen)
  123. throwsIOException
  124. {
  125. getBufIfOpen();//Checkforclosedstream
  126. if((off|len|(off+len)|(b.length-(off+len)))<0){
  127. thrownewIndexOutOfBoundsException();
  128. }elseif(len==0){
  129. return0;
  130. }
  131. //读取到指定长度的数据才前往
  132. intn=0;
  133. for(;;){
  134. intnread=read1(b,off+n,len-n);
  135. if(nread<=0)
  136. return(n==0)?nread:n;
  137. n+=nread;
  138. if(n>=len)
  139. returnn;
  140. //ifnotclosedbutnobytesavailable,return
  141. InputStreaminput=in;
  142. if(input!=null&&input.available()<=0)
  143. returnn;
  144. }
  145. }
  146. //疏忽n个字节
  147. publicsynchronizedlongskip(longn)throwsIOException{
  148. getBufIfOpen();//Checkforclosedstream
  149. if(n<=0){
  150. return0;
  151. }
  152. longavail=count-pos;
  153. if(avail<=0){
  154. //Ifnomarkpositionsetthendontkeepinbuffer
  155. if(markpos<0)
  156. returngetInIfOpen().skip(n);
  157. //Fillinbuffertosavebytesforreset
  158. fill();
  159. avail=count-pos;
  160. if(avail<=0)
  161. return0;
  162. }
  163. longskipped=(avail<n)?avail:n;
  164. pos+=skipped;
  165. returnskipped;
  166. }
  167. //下一个字节是不是存可读
  168. publicsynchronizedintavailable()throwsIOException{
  169. intn=count-pos;
  170. intavail=getInIfOpen().available();
  171. returnn>(Integer.MAX_VALUE-avail)
  172. ?Integer.MAX_VALUE
  173. :n+avail;
  174. }
  175. //标志“缓冲区”中以后地位。
  176. //readlimit是marklimit,关于marklimit的感化,参考前面的申明。
  177. publicsynchronizedvoidmark(intreadlimit){
  178. marklimit=readlimit;
  179. markpos=pos;
  180. }
  181. //将“缓冲区”中以后地位重置到mark()所标志的地位
  182. publicsynchronizedvoidreset()throwsIOException{
  183. getBufIfOpen();//Causeexceptionifclosed
  184. if(markpos<0)
  185. thrownewIOException("Resettingtoinvalidmark");
  186. pos=markpos;
  187. }
  188. publicbooleanmarkSupported(){
  189. returntrue;
  190. }
  191. //封闭输出流
  192. publicvoidclose()throwsIOException{
  193. byte[]buffer;
  194. while((buffer=buf)!=null){
  195. if(bufUpdater.compareAndSet(this,buffer,null)){
  196. InputStreaminput=in;
  197. in=null;
  198. if(input!=null)
  199. input.close();
  200. return;
  201. }
  202. //ElseretryincaseanewbufwasCASedinfill()
  203. }
  204. }
  205. }
复制代码
<p>
C#是盗用了Java的源代码,仿照开发的,原因是Java是开源的啊,盗了也白盗,还有一点,开发C#语言的团队是就是开发Java语言的团队,是微软重金挖过去的啊
admin 该用户已被删除
沙发
发表于 2015-1-20 12:33:54 | 只看该作者
Java 不同于一般的编译执行计算机语言和解释执行计算机语言。它首先将源代码编译成二进制字节码(bytecode),然后依赖各种不同平台上的虚拟机来解释执行字节码。从而实现了“一次编译、到处执行”的跨平台特性。
灵魂腐蚀 该用户已被删除
板凳
发表于 2015-1-29 07:09:05 | 只看该作者
是一种突破用户端机器环境和CPU
活着的死人 该用户已被删除
地板
发表于 2015-2-5 23:56:32 | 只看该作者
象、泛型编程的特性,广泛应用于企业级Web应用开发和移动应用开发。
不帅 该用户已被删除
5#
发表于 2015-2-14 09:28:11 | 只看该作者
让你能够真正掌握接口或抽象类的应用,从而在原来的Java语言基础上跃进一步,更重要的是,设计模式反复向你强调一个宗旨:要让你的程序尽可能的可重用。
简单生活 该用户已被删除
6#
发表于 2015-3-4 05:17:21 | 只看该作者
你就该学一学Servlet了。Servlet就是服务器端小程序,他负责生成发送给客户端的HTML文件。JSP在执行时,也是先转换成Servlet再运行的。虽说JSP理论上可以完全取代Servlet,这也是SUN推出JSP的本意,可是Servlet用来控制流程跳转还是挺方便的,也令程序更清晰。接下来你应该学习一下Javabean了,可能你早就看不管JSP在HTML中嵌Java代码的混乱方式了,这种方式跟ASP又有什么区别呢?
透明 该用户已被删除
7#
发表于 2015-3-11 17:29:35 | 只看该作者
J2SE开发桌面应用软件比起 VC,VB,DEPHI这些传统开发语言来说,优势好象并不明显。J2ME对于初学者来说,好象又有点深奥,而且一般开发者很难有开发环境。
飘飘悠悠 该用户已被删除
8#
发表于 2015-3-27 07:09:20 | 只看该作者
《JAVA语言程序设计》或《JAVA从入门到精通》这两本书开始学,等你编程有感觉的时候也可以回看一下。《JAVA读书笔记》这本书,因为讲的代码很多,也很容易看懂,涉及到面也到位。是你学习技术巩固的好书,学完后就看看《JAVA编程思想》这本书,找找一个自己写的代码跟书上的代码有什么不一样。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2025-1-5 21:31

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表