﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-afrag-随笔分类-Java随想</title><link>http://www.blogjava.net/afrag/category/4298.html</link><description>记录学习和成长的历程</description><language>zh-cn</language><lastBuildDate>Mon, 05 Apr 2010 13:08:19 GMT</lastBuildDate><pubDate>Mon, 05 Apr 2010 13:08:19 GMT</pubDate><ttl>60</ttl><item><title>Java SE 7新特性之文件操作（6） - 创建和读写文件 </title><link>http://www.blogjava.net/afrag/archive/2010/04/05/317501.html</link><dc:creator>afrag</dc:creator><author>afrag</author><pubDate>Mon, 05 Apr 2010 09:30:00 GMT</pubDate><guid>http://www.blogjava.net/afrag/archive/2010/04/05/317501.html</guid><wfw:comment>http://www.blogjava.net/afrag/comments/317501.html</wfw:comment><comments>http://www.blogjava.net/afrag/archive/2010/04/05/317501.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/afrag/comments/commentRss/317501.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/afrag/services/trackbacks/317501.html</trackback:ping><description><![CDATA[转自 <a title="开发者的天空" href="httP//www.developersky.net">开发者的天空</a><br />
<br />
本文中我们来讨论在<span href="http://www.developersky.net/tag.php?name=NIO2" onclick="tagshow(event)" class="t_tag">NIO2</span>中怎样<span href="http://www.developersky.net/tag.php?name=%E5%88%9B%E5%BB%BA%E6%96%87%E4%BB%B6" onclick="tagshow(event)" class="t_tag">创建文件</span>、读取文件和写文件。NIO2提供了多种创建
文件的方法，使得我们在创建文件的时候就可以指定文件的某些初始属性。例如在支持POSIX的文件系统上指定文件的所有者，访问权限等。关于文件的属性，
请看上一篇文章<a href="http://www.developersky.net/thread-20-1-1.html" target="_blank"><span href="http://www.developersky.net/tag.php?name=Java" onclick="tagshow(event)" class="t_tag">Java</span> SE 7新特性之<span href="http://www.developersky.net/tag.php?name=%E6%96%87%E4%BB%B6%E6%93%8D%E4%BD%9C" onclick="tagshow(event)" class="t_tag">文件操作</span>（5） - 管理元数据</a><br />
<strong><font size="4">创建文件</font></strong><br />
可以调用createFile(FileAttribute&lt;?&gt;)方法创建一个空文件。该方法的参数就是文件的初始属性。下面的例子是怎样
在创建文件的时候赋予该文件某些权限的属性：<br />
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">Path&nbsp;sourceFile&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />;<br />
Path&nbsp;newFile&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />;<br />
PosixFileAttributes&nbsp;attrs&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;Attributes.readPosixFileAttributes(sourceFile);<br />
FileAttribute</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Set</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">PosixFilePermission</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;attr&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PosixFilePermissions.asFileAttribute(attrs.permissions());<br />
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;file.createFile(attr);<br />
}&nbsp;</span><span style="color: #0000ff;">catch</span><span style="color: #000000;">&nbsp;(IOException&nbsp;x)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">unable&nbsp;to&nbsp;create&nbsp;the&nbsp;file</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">}</span></div>
如
果在调用该方法的时候没有传入任何参数，那么创建的文件将具有缺省的文件属性。下面的代码创建了一个具有缺省文件属性的文件：<em><br />
</em>
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">Path&nbsp;file&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />;<br />
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;file.createFile();&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">Create&nbsp;the&nbsp;empty&nbsp;file&nbsp;with&nbsp;default&nbsp;permissions,&nbsp;etc.</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">}&nbsp;</span><span style="color: #0000ff;">catch</span><span style="color: #000000;">&nbsp;(FileAlreadyExists&nbsp;x)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.err.format(</span><span style="color: #000000;">"</span><span style="color: #000000;">file&nbsp;named&nbsp;%s&nbsp;already&nbsp;exists%n</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;file);<br />
}&nbsp;</span><span style="color: #0000ff;">catch</span><span style="color: #000000;">&nbsp;(IOException&nbsp;x)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">Some&nbsp;other&nbsp;sort&nbsp;of&nbsp;failure,&nbsp;such&nbsp;as&nbsp;permissions.</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;System.err.format(</span><span style="color: #000000;">"</span><span style="color: #000000;">createFile&nbsp;error:&nbsp;%s%n</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;x);<br />
}</span></div>
如
果要创建的文件已经存在，该方法会抛出异常。<br />
注意在调用createFile方法时，检查文件是否存在和创建具有特定的属性的文件是在同一个原子操作中。<br />
还可以使用newOutputSteam方法来创建文件，在本文的后面我们会讲到怎样使用newOutputStream方法来创建文件。<br />
<strong><font size="4">通过Stream I/O读文件</font></strong><br />
我们可以通过newInputStream（OpenOption...)方法打开和读取文件。这个方法返回一个unbuffered输入流（input
stream），我们可以用它来从文件中读取字节内容。<em><br />
</em>
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">Path&nbsp;file&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />;<br />
InputStream&nbsp;in&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;in&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;file.newInputStream();<br />
&nbsp;&nbsp;&nbsp;&nbsp;BufferedReader&nbsp;reader&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;BufferedReader(</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;InputStreamReader(in));<br />
&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;line&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;((line&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;reader.readLine())&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(line);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}&nbsp;</span><span style="color: #0000ff;">catch</span><span style="color: #000000;">&nbsp;(IOException&nbsp;x)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.err.println(x);<br />
}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(in&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;in.close();<br />
}</span></div>
注
意该方法接受可变个数的参数，参数类型为OpenOption，指定了文件怎样打开。如果不传入参数，则使用默认的READ方式打开。READ方式是所有
的实现都支持的方式。有一些实现也支持其他的打开方式。<br />
如果传入的OpenOption或其组合不正确，会抛出异常。如果程序没有读权限或I/O错误，也会抛出异常。<br />
Creating and Writing a File by Using Stream I/O<br />
<strong><font size="4">使用Stream I/O来创建和写文件</font></strong><br />
我们可以使用newOutputStream方法来创建文件、扩展文件或覆盖已有文件。这个方法为了写文件而打开或创建文件，该方法返回一个
unbuffered的输出流（output stream）。newOutputStream方法有两种形式：<br />
<ul><br />
    <li>newOutputStream(OpenOption...)<br />
    </li>
    <li>newOutputStream(Set&lt;? extends OpenOption&gt;,
    FileAttribute&lt;?&gt;...)<br />
    </li>
</ul>
<br />
这两种形式都接受一组OpenOption作为参数，第二种形式还允许指定初始的文件属性。这个方法支持的StandardOpenOption有：<br />
<ul><br />
    <li>WRITE &#8211;为了写访问而打开该文件. <br />
    </li>
    <li>APPEND &#8211; 将新数据扩展在文件的末尾。该选项和WRITE或CREATE选项一起使用。<br />
    </li>
    <li>TRUNCATE_EXISTING &#8211; 将文件截断为0字节长. 该选项和WRITE选项一起使用来覆盖原有文件。 <br />
    </li>
    <li>CREATE_NEW &#8211; 创建一个新的文件。如果原来的文件存在这抛出异常。<br />
    </li>
    <li>CREATE &#8211; 如果原文件存在这打开它，否则创建新的文件。<br />
    </li>
    <li>DELETE_ON_CLOSE &#8211; 当Stream关闭时删除该文件。这个选项对临时文件比较有用。<br />
    </li>
    <li>SPARSE &#8211; 表明新创建的文件是Sparse文件. 关于Sparse文件的具体信息请看<a href="http://space.itpub.net/8242091/viewspace-619756" target="_blank">http://space.itpub.net/8242091/viewspace-619756</a>。<br />
    </li>
    <li>SYNC &#8211; 保持该文件（包括内容和元数据）与底层存储设备同步。 <br />
    </li>
    <li>DSYNC &#8211; 保持文件内容与底层存储设备同步。<br />
    </li>
</ul>
<br />
如果没有指定OpenOption，该方法的行为是：如果文件不存在，则创建新文件；如果文件存在，那么截断它。也就是说缺省的选择是CREATE和
TRUNCATE_EXISTING选项的组合。<br />
下面的代码打开一个<span href="http://www.developersky.net/tag.php?name=%E6%97%A5%E5%BF%97" onclick="tagshow(event)" class="t_tag">日志</span>文件，如果文件不存在，则创建一个新文件。如果文件
存在，这将新的内容扩展到文件尾部。<em><br />
</em>
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;java.nio.file.StandardOpenOption.</span><span style="color: #000000;">*</span><span style="color: #000000;">;<br />
<br />
Path&nbsp;logfile&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />;<br />
<br />
</span><span style="color: #008000;">//</span><span style="color: #008000;">Convert&nbsp;the&nbsp;string&nbsp;to&nbsp;a&nbsp;byte&nbsp;array.</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">String&nbsp;s&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />;<br />
</span><span style="color: #0000ff;">byte</span><span style="color: #000000;">&nbsp;data[]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;s.getBytes();<br />
<br />
OutputStream&nbsp;out&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;out&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;BufferedOutputStream(logfile.newOutputStream(CREATE,&nbsp;APPEND));<br />
&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;out.write(data,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;data.length);<br />
}&nbsp;</span><span style="color: #0000ff;">catch</span><span style="color: #000000;">&nbsp;(IOException&nbsp;x)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.err.println(x);<br />
}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(out&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.flush();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}</span></div>
<br />
<strong><font size="4">使用Channel I/O来<span href="http://www.developersky.net/tag.php?name=%E8%AF%BB%E5%86%99%E6%96%87%E4%BB%B6" onclick="tagshow(event)" class="t_tag">读写文件</span></font></strong><br />
Stream I/O每次读取一个字符，Channel
I/O每次读取一个缓冲块的数据。ByteChannel接口提供了基本的读写功能。SeekableByteChannel扩展了
ByteChannel并提供了维护一个channel中的位置并改变该位置的能力。SeekableByteChannel还支持截断文件和查询文件大
小的功能。<br />
移动到文件中不同的位置，从该位置开始读或写的能力使我们可以<span href="http://www.developersky.net/tag.php?name=%E9%9A%8F%E6%9C%BA%E8%AE%BF%E9%97%AE%E6%96%87%E4%BB%B6" onclick="tagshow(event)" class="t_tag">随机访问文件</span>。有两种形式的
newByteChannel方法可以用来读或写文件，这两种形式和newOutputStream方法一样。<br />
<ul><br />
    <li>newByteChannel(OpenOption...)<br />
    </li>
    <li>newByteChannel(Set&lt;? extends OpenOption&gt;,
    FileAttribute&lt;?&gt;...)<br />
    </li>
</ul>
<br />
这两个方法都允许指定OpenOption，newOutputStream所支持的选择这里也支持，而且这里还支持另外一个选项READ，因为
SeekableByteChannel既支持读也支持写。<br />
如果选项是READ，那么该channel就是为了读访问打开。如果选项是WRITE或APPEND，则该channel就是为了写访问打开。如果没有指
定，该channel默认是为了读打开。<br />
下面的代码从文件中读取内容并输出到控制台上：<em><br />
</em>
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">SeekableByteChannel&nbsp;sbc&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;sbc&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;file.newByteChannel();&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">Defaults&nbsp;to&nbsp;READ</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;ByteBuffer&nbsp;buf&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;ByteBuffer.allocate(</span><span style="color: #000000;">10</span><span style="color: #000000;">);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">Read&nbsp;the&nbsp;bytes&nbsp;with&nbsp;the&nbsp;proper&nbsp;encoding&nbsp;for&nbsp;this&nbsp;platform.<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">If&nbsp;you&nbsp;skip&nbsp;this&nbsp;step,&nbsp;you&nbsp;might&nbsp;see&nbsp;something&nbsp;that&nbsp;looks&nbsp;like&nbsp;Chinese<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">characters&nbsp;when&nbsp;you&nbsp;expect&nbsp;Latin-style&nbsp;characters.</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;encoding&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;System.getProperty(</span><span style="color: #000000;">"</span><span style="color: #000000;">file.encoding</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(sbc.read(buf)&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf.rewind();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.print(Charset.forName(encoding).decode(buf));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf.flip();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}&nbsp;</span><span style="color: #0000ff;">catch</span><span style="color: #000000;">&nbsp;(IOException&nbsp;x)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">caught&nbsp;exception:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;x);<br />
}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(sbc&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;sbc.close();<br />
}</span></div>
下
面的代码是为了UNIX或其他支持POSIX的文件系统编写的。这段代码创建一个新的日志文件或者扩展原有的日志文件，该日志文件创建时指定了访问权限
（所有者有读写权限，同组用户只有读权限，其他用户没有读权限）。
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;java.nio.file.StandardCopyOption.</span><span style="color: #000000;">*</span><span style="color: #000000;">;<br />
<br />
</span><span style="color: #008000;">//</span><span style="color: #008000;">Create&nbsp;the&nbsp;set&nbsp;of&nbsp;options&nbsp;for&nbsp;appending&nbsp;to&nbsp;the&nbsp;file.</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">Set</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">OpenOptions</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;options&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;HashSet</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">OpenOption</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">();<br />
options.add(APPEND);<br />
options.add(CREATE);<br />
<br />
</span><span style="color: #008000;">//</span><span style="color: #008000;">Create&nbsp;the&nbsp;custom&nbsp;permissions&nbsp;attribute.</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">Set</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">PosixFilePermission</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;perms&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;PosixFilePermissions.fromString(</span><span style="color: #000000;">"</span><span style="color: #000000;">rw-r------</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
FileAttribute</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Set</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">PosixFilePermission</span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;">&nbsp;attr&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;PosixFilePermissions.asFileAttribute(perms);<br />
<br />
</span><span style="color: #008000;">//</span><span style="color: #008000;">Convert&nbsp;the&nbsp;string&nbsp;to&nbsp;a&nbsp;ByetBuffer.</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">String&nbsp;s&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />;<br />
</span><span style="color: #0000ff;">byte</span><span style="color: #000000;">&nbsp;data[]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;s.getBytes();<br />
ByteBuffer&nbsp;bb&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;ByteBuffer.wrap(data);<br />
<br />
SeekableByteChannel&nbsp;sbc&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;sbc&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;file.newByteChannel(options,&nbsp;attr);<br />
&nbsp;&nbsp;&nbsp;&nbsp;sbc.write(bb);<br />
}&nbsp;</span><span style="color: #0000ff;">catch</span><span style="color: #000000;">&nbsp;(IOException&nbsp;x)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">exception&nbsp;thrown:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;x);<br />
}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(sbc&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;sbc.close();<br />
}</span></div>
<img src ="http://www.blogjava.net/afrag/aggbug/317501.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/afrag/" target="_blank">afrag</a> 2010-04-05 17:30 <a href="http://www.blogjava.net/afrag/archive/2010/04/05/317501.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java SE 7文件操作新特性之一些相关概念</title><link>http://www.blogjava.net/afrag/archive/2010/03/29/316789.html</link><dc:creator>afrag</dc:creator><author>afrag</author><pubDate>Mon, 29 Mar 2010 02:02:00 GMT</pubDate><guid>http://www.blogjava.net/afrag/archive/2010/03/29/316789.html</guid><wfw:comment>http://www.blogjava.net/afrag/comments/316789.html</wfw:comment><comments>http://www.blogjava.net/afrag/archive/2010/03/29/316789.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/afrag/comments/commentRss/316789.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/afrag/services/trackbacks/316789.html</trackback:ping><description><![CDATA[转自<a href="http://www.developersky.net">开发者的天空</a><br />
<br />
Path类提供了很多方法来对文件和目录进行读、写和其他的操作。在看这些方法之前，我们先需要了解一些其他的概念：<br />
<strong></strong><br />
Varargs实际上是Variable number of arguments的缩写，也就是可变数目的参数。例如在下面的方法声明中，CopyOption参数后面的省略号表明这个方法接受可变个数的参数。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Path moveTo(Path, CopyOption...)<br />
当一个方法可以接受可变数目的参数时，你可以传入以逗号分隔的多个参数，或者传入一个数组。<br />
对于上面的moveTo方法，可以这样调用：<br />
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;java.nio.file.StandardCopyOption.</span><span style="color: #000000;">*</span><span style="color: #000000;">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Path&nbsp;orig&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" />;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Path&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" />;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;orig.moveTo(</span><span style="color: #0000ff;">new</span><span style="color: #000000;">,&nbsp;REPLACE_EXISTING,&nbsp;ATOMIC_MOVE);</span></div>
<br />
<strong></strong><br />
Path的很多方法在文件系统上执行的操作都是原子操作，例如moveTo方法。原子操作是指不会被中断或不会部分执行的操作。操作要么是完全成功，要么是完全失败。当有多个进程操作同文件系统的相同的区域的时候这一点就很重要。<br />
<br />
<strong></strong><br />
很多的文件I/O方法支持方法链的概念。<br />
调用第一个方法会返回一个对象，我们可以直接调用这个对象的方法，这个方法依然返回一个对象，我们又可以直接调用该对象的方法，就这样持续下去。例如：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String value = Charset.defaultCharset().decode(buf).toString();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UserPrincipal group = file.getFileSystem().getUserPrincipalLookupService().lookupPrincipalByName("me");<br />
这个技术能够使我们编写更加紧凑的代码，避免声明一些我们不需要的临时变量。<br />
<br />
<strong></strong><br />
Path类实现了FileRef接口。FileRef接口包含了定位文件和访问文件的方法。<br />
<br />
<strong></strong><br />
Path类有两个方法能够接受带模式匹配的参数。下面是这种参数的规则：<br />
星号*匹配任意数目的字符（也可能是没有）<br />
两个星号**同样是代表任意数目的字符，不同的是这个匹配可以穿越目录边界。例如 c:"a**"bar可以匹配c:"abc"bar，也可以匹配c:"am"cn"bar。<br />
问号?匹配一个字符<br />
花括号{}表明子模式的集合，例如{sun,moon,stars}可以匹配'sun','moon'或&#8216;stars&#8217;；{temp*,tmp*}可以匹配以temp或tmp开始的任意字符串。<br />
要匹配*,?或其他的特殊字符，可以使用转义符"。例如""匹配单个的"，"?匹配问号。<br />
方括号[]表示一组单独的字符，当使用了-的时候，也代表一个范围的字符，例如：<br />
[aeiou]匹配任何单独的元音字符，[0-9]匹配任意数字，[A-Z]匹配任意大写字母，[a-z,A-Z]匹配任意大写或小写字母。在方括号中，星号、问号和"都只是表示它们自身，不再作为特殊符号。<br />
下面是一些例子：<br />
*.html匹配所有以.html结尾的字符串。<br />
???匹配所有长度为3的字符串<br />
*[0-9]*匹配所有包含有数字的字符串<br />
*.{html,htm,pdf}匹配所有以.html,.html或.pdf结尾的字符串<br />
a?*.java匹配所有以a开头，后面跟至少一个字符，然后以.java结尾的字符串。<br />
{foo*,*[0-9]*}匹配以foo开头的字符串或包含有数字的字符串。<br />
关于参数中的模式的使用，请参考FileSystem类的getPathMatcher方法的帮助文档。<br />
如果这种模式匹配仍然不能够满足需要，我们还可以使用正则表达式。<br />
<br />
<br />
<strong></strong><br />
Path会指向文件或者目录，但是我们还不能确定这个文件或者目录是否存在，是否可读，是否可写，是否可以执行。要确定文件/目录是否存在以及程序是否可以访问该文件/目录，可以使用checkAccess(AccessMode...)方法。可选的AccessMode有：<br />
&nbsp;&nbsp;&nbsp; * READ &#8211; 检查文件/目录是否存在以及程序是否有权限读该文件/目录<br />
&nbsp;&nbsp;&nbsp; * WRITE &#8211; 检查文件/目录是否存在以及程序是否有权限写该文件/目录<br />
&nbsp;&nbsp;&nbsp; * EXECUTE &#8211; 检查文件/目录是否存在以及程序在该文件/目录上是否有执行权限<br />
如果调用checkAccess的时候没有传入任何参数，该方法只是检查文件是否存在。<br />
下面的例子演示了怎样验证文件是否存在以及程序是否有读和执行的权限。<br />
import static java.nio.file.AccessMode.*;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br />
&nbsp;&nbsp;&nbsp; Path file = ...;<br />
&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file.checkAccess(READ, EXECUTE);<br />
&nbsp;&nbsp;&nbsp; } catch (IOException x) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Logic for error condition...<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; //Logic for executable file...<br />
需要注意的是，当checkAccess执行完之后，文件的权限可能被其他的用户（例如系统管理员）修改。这实际上是很多应用程序都有的安全性的问题。如果你感兴趣，可以搜索TOCTTOU （time of check to time of use）。<br />
<br />
<strong></strong><br />
当文件系统中存在符号链接的时候，可能两个不同的路径会指向同一个文件或目录。方法isSamePath会比较两个Path来检查它们是否指向同一个文件/目录。<br />
&nbsp;&nbsp;&nbsp; Path p1 = ...;<br />
&nbsp;&nbsp;&nbsp; Path p2 = ...;<br />
<br />
&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (p1.isSameFile(p2)) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Logic when the paths locate the same file<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; } catch (IOException x) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Logic for error condition...<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br />
&nbsp;&nbsp;&nbsp; }
<img src ="http://www.blogjava.net/afrag/aggbug/316789.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/afrag/" target="_blank">afrag</a> 2010-03-29 10:02 <a href="http://www.blogjava.net/afrag/archive/2010/03/29/316789.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring AOP中MethodBeforeAdvice、AfterReturningAdvice和MethodInterceptor的执行顺序</title><link>http://www.blogjava.net/afrag/archive/2005/11/02/17861.html</link><dc:creator>afrag</dc:creator><author>afrag</author><pubDate>Wed, 02 Nov 2005 10:10:00 GMT</pubDate><guid>http://www.blogjava.net/afrag/archive/2005/11/02/17861.html</guid><wfw:comment>http://www.blogjava.net/afrag/comments/17861.html</wfw:comment><comments>http://www.blogjava.net/afrag/archive/2005/11/02/17861.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/afrag/comments/commentRss/17861.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/afrag/services/trackbacks/17861.html</trackback:ping><description><![CDATA[<P>在Spring 的AOP中，如果一个Proxy同时实现MethodBeforeAdvice、AfterReturningAdvice和MethodInterceptor接口，那么这三个Advice的执行顺序是什么样的呢？<BR>经过试验，是和xml文件中的定义顺序有关的。<BR>如果Proxy的接口实现定义为<BR>      <property name="interceptorNames"><BR>          <list><BR>            <value>MethodBeforeAdvice</value><BR>            <value>AfterReturningAdvice</value><BR>            <value>MethodInterceptor</value><BR>          </list><BR>      </property><BR>那么执行的结果是<BR>MethodBeforeAdvice</P>
<P>MethodInterceptor: before call</P>
<P>Really method excuting</P>
<P>MethodInterceptor: after call</P>
<P>AfterReturningAdvice<BR><BR>也就是说，执行顺序是：MethodBeforeAdvice，MethodInterceptor的调用前的部分，目标方法，MethodInterceptor的调用后的部分，AfterReturningAdvice。<BR><BR>如果proxy的定义是<BR>      <property name="interceptorNames"><BR>          <list><BR>            <value>MethodBeforeAdvice</value><BR>            <value>MethodInterceptor</value><BR>            <value>AfterReturningAdvice</value><BR>          </list><BR>      </property><BR>执行的结果是<BR>MethodBeforeAdvice</P>
<P>MethodInterceptor: before call</P>
<P>Really method excuting</P>
<P>AfterReturningAdvice</P>
<P>MethodInterceptor: after call<BR>也就是说，执行的顺序是：MethodBeforeAdvice，MethodInterceptor的调用前的部分，目标方法，AfterReturningAdvice，MethodInterceptor的调用后的部分。<BR><BR>如果proxy的定义是<BR>      <property name="interceptorNames"><BR>          <list><BR>            <value>MethodInterceptor</value><BR>            <value>MethodBeforeAdvice</value><BR>            <value>AfterReturningAdvice</value><BR>          </list><BR>      </property><BR>执行的结果是：<BR>MethodInterceptor: before call</P>
<P>MethodBeforeAdvice</P>
<P>Really method excuting</P>
<P>AfterReturningAdvice</P>
<P>MethodInterceptor: after call<BR>也就是说,执行的顺序是：MethodInterceptor的调用前的部分，MethodBeforeAdvice，目标方法，AfterReturningAdvice，MethodInterceptor的调用后的部分。<BR>以上的顺序是在springframework 1.2.5中测试的。<BR></P><img src ="http://www.blogjava.net/afrag/aggbug/17861.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/afrag/" target="_blank">afrag</a> 2005-11-02 18:10 <a href="http://www.blogjava.net/afrag/archive/2005/11/02/17861.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>