<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>-Flyぁ梦- &#187; Buffer</title>
	<atom:link href="http://blog.11034.org/tag/buffer/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.11034.org</link>
	<description></description>
	<lastBuildDate>Sun, 22 Jun 2025 08:59:05 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.2.38</generator>
	<item>
		<title>Java学习之IO与NIO篇</title>
		<link>http://blog.11034.org/2010-08/java_io_nio.html</link>
		<comments>http://blog.11034.org/2010-08/java_io_nio.html#comments</comments>
		<pubDate>Wed, 04 Aug 2010 17:12:35 +0000</pubDate>
		<dc:creator><![CDATA[-Flyぁ梦-]]></dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Buffer]]></category>
		<category><![CDATA[io]]></category>
		<category><![CDATA[异步IO]]></category>

		<guid isPermaLink="false">http://blog.stariy.info/?p=147</guid>
		<description><![CDATA[Java的IO相较于其他语言，感觉是比较抽象和复杂的，当然等你理解了它并且熟练了，它的强大性就马上体现出来了。 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Java的IO相较于其他语言，感觉是比较抽象和复杂的，当然等你理解了它并且熟练了，它的强大性就马上体现出来了。其实本来只是想写nio的，把io也顺带理一下吧。</p>
<p>Java的io最重要的一个概念就是流，就像一个水管插在文件和终端之间，每个字节都是一滴水，按顺序单方向地流动，这样理解不知道是不是容易些？流主要分以下几种类型：<br />
<span id="more-147"></span></p>
<ul>
<li>输入流和输出流：就是流的方向。 InputStream和Reader是输入，OutputStream和Writer是输出，很简单</li>
<li>字节流和字符流：流的最小单位，字节流好理解，字符流是因为gbk和Unicode等的存在，单独一个字节是无法表示一个字符的，2个字节为单位读取。InputStream和OutputStream是字节流，Reader和Writer是字符流</li>
<li>基础流和封装流：以上四种都是基础流，提供的API基本都是get()一个字节/字符，write()一个字节/字符；封装流将基础流包装了一下，提供了更多的功能，比如最常用的BufferedStream，用来缓存流从而提高IO效率；DataStream，提供读写Java基本类型的流，可以直接写入一个int、double、UTFString等；StreamReader、StreamWriter，将字节流转换为字符流；其他还有ByteArrayStream、FileStream等，字面意思就很明白了</li>
</ul>
<p>弄清楚这些，其实Java IO基本就能搞明白了。传说中的三层流封装就很明了了，第一层基础流，比如InputSream，第二层InputStreamReader，转换为字符流，第三层再包装一个BufferedReader，提高IO效率，很清楚也很简单，不要被这个流程搞晕了。大致上基础io包也就这些东西了。</p>
<p>接下来就讲讲刚看的nio包，nio比基础io更抽象更难用，其实基础io功能也很强大了，所以一直没鼓起勇气去学nio。在百度文库下到一个不错的教程，2天就看完了，讲讲自己的心得。</p>
<p>先说nio中比较易用且实用的，就是各种Buffer，最基础的ByteBuffer，CharBuffer也不错，还有各种其他类型的Buffer。Buffer有position、limit、capacity属性。position为当前buffer操作到了哪个位置，包括读和写，limit为用户可自己限制的此buffer的结尾位置，capacity就是buffer的大小，综合起来就是：0 &lt;=position &lt;= limit &lt;= capacity &lt;= size of array。主要的API有flip()，主要用于将数据读入到buffer后，将limit设为当前的position，然后将position设为0，就可以从头到尾把所有的数据读出来了。</p>
<p>再说说文件读写中的FileChannel，这个是一个nio中新的概念，类似于stream，可以从FileStream中通过getChannel()获取，然后FileChannel的read(ByteBuffer)方法直接将字节流读入buffer，操作挺方便；官方介绍FileChannel说这是个可读可写并且双向的流，可读可写倒确实，不过双向我暂时没有看出来，文件copy的过程中还是需要建立1个InputStream获得一个FileChannel，1个OutputStream获得一个FileChannel，不能用1个FileChannel来搞定，双向意义何在？</p>
<p>综合FileChannel和Buffer举个例子：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #003399;">FileInputStream</span> fis <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">FileInputStream</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">File</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;a.txt&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
FileChannel fin <span style="color: #339933;">=</span> fis.<span style="color: #006633;">getChannel</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003399;">FileOutputStream</span> fos <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">FileOutputStream</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">File</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;b.txt&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
FileChannel fout <span style="color: #339933;">=</span> fos.<span style="color: #006633;">getChannel</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
ByteBuffer buffer <span style="color: #339933;">=</span> ByteBuffer.<span style="color: #006633;">allocate</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1024</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//1024字节的buffer</span>
<span style="color: #000000; font-weight: bold;">while</span><span style="color: #009900;">&#40;</span>fin.<span style="color: #006633;">read</span><span style="color: #009900;">&#40;</span>buffer<span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
     buffer.<span style="color: #006633;">flip</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//buffer写满，position重新置0，limit置为结尾，方便使用</span>
     fout.<span style="color: #006633;">write</span><span style="color: #009900;">&#40;</span>buffer<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
     buffer.<span style="color: #006633;">clear</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #666666; font-style: italic;">//清空buffer</span>
<span style="color: #009900;">&#125;</span>
fin.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
fout.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
fis.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
fos.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>还有一个也比较实用的是Charset和对应的CharsetEncoder和CharsetDecoder，可以将字节流与不同的字符流之间相互转换。</p>
<p>最后是nio中最麻烦应该也是最强大的地方，异步IO，这儿涉及很多新的概念和类，Selector、ServerSocketChannel、SelectionKey，注册事件、监听事件、处理事件等，我就看了一个下午左右，理解也不是非常深，大致知道这些类怎么串起来用。还是看程序来的学得快，程序我放到附件中，理解了NIOServer和NIOClient，就有了基础了。当然程序中比较缺乏的一点就是处理事件的时候是单线程的，这样事件队列一旦越积越多，速度就慢了，开几个线程同时来响应事件是比较好的方案。</p>
<p>nio中还有其他的一些东西，比如Buffer的一些深入 direct Buffer，越过临时buffer提高速度；Memory-mapped file I/O，提高文件读写速度；File locking（这个还不是很懂）。</p>
<p>又掌握了Java中一个很重要的类包，还是挺开心的，坚持写完这篇日志也是受了gstar博客大牛的影响，多写写技术blog哈~接下来的目标，当然是把nio好好再消化下，然后自我觉得没有掌握而觉得很重要的还有java.util.concurrency包、java.security包、java.rmi包，主要这些平时比较少用，嗯，慢慢来~</p>
<p>附：包括一个NIO的异步IO的2个示范类，随意看看</p>
<p><a href="/wp-content/uploads/2010/08/NIO.zip" rel="attachment">NIO异步IO示范</a></p>
<h4  class="related_post_title">看看 Buffer , io , 异步IO</h4><ul class="related_post"><li>2013-05-20 -- <a target="_blank" href="http://blog.11034.org/2013-05/coyote.html" title="Tomcat的Connector：Coyote">Tomcat的Connector：Coyote</a></li></ul><h4 class="related_post_title">看看 Java </h4><ul class="related_post"><li>2016-09-09 -- <a target="_blank" href="http://blog.11034.org/2016-09/64bits_linux_arena_memory.html" title="64位Linux下Java进程堆外内存迷之64M问题">64位Linux下Java进程堆外内存迷之64M问题</a></li><li>2016-08-18 -- <a target="_blank" href="http://blog.11034.org/2016-08/java_concurrency_in_practice.html" title="读java concurrency in practice">读java concurrency in practice</a></li><li>2016-08-05 -- <a target="_blank" href="http://blog.11034.org/2016-08/thread_stop.html" title="线程清理">线程清理</a></li><li>2016-06-21 -- <a target="_blank" href="http://blog.11034.org/2016-06/futuretask.html" title="FutureTask简单分析和用法">FutureTask简单分析和用法</a></li><li>2016-06-21 -- <a target="_blank" href="http://blog.11034.org/2016-06/semaphore.html" title="Semaphore简单分析">Semaphore简单分析</a></li>]]></content:encoded>
			<wfw:commentRss>http://blog.11034.org/2010-08/java_io_nio.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
