package com.java.io;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel; public class GetChannel {
private static final int BSIZE = 1024; @SuppressWarnings("resource")
public static void main(String[] args) throws Exception {
// 获取通道,该通道允许写操作
FileChannel fc = new FileOutputStream("data.txt").getChannel();
// 将字节数组包装到缓冲区中
fc.write(ByteBuffer.wrap("Some text ".getBytes()));
// 关闭通道
fc.close(); // 随机读写文件流创建的管道
fc = new RandomAccessFile("data.txt", "rw").getChannel();
// fc.position()计算从文件的开始到当前位置之间的字节数
// 设置此通道的文件位置,fc.size()此通道的文件的当前大小,该条语句执行后,通道位置处于文件的末尾
fc.position(fc.size()); // Move to the end
fc.write(ByteBuffer.wrap("Some more".getBytes()));
fc.close(); // Read the file:
fc = new FileInputStream("data.txt").getChannel();
ByteBuffer buff = ByteBuffer.allocate(BSIZE);
// 将文件内容读到指定的缓冲区中
fc.read(buff);
//buffer.flip();一定得有,如果没有,就是从文件最后开始读取的,当然读出来的都是byte=0时候的字符。
//通过buffer.flip();这个语句,就能把buffer的当前位置更改为buffer缓冲区的第一个位置。
buff.flip();
while(buff.hasRemaining()){
System.out.print((char)buff.get());
}
}
}
对于只读访问,我们必须显式地使用静态的allocate()方法来分配ByteBuffer。 nio的目标就是快速移动大量数据,因此ByteBuffer的大小就显得尤为重要一一实际上,这里使用的lK可能比我们通常要使用的小一点(必须通过实际运行应用程序来找到最佳尺寸).
 
一旦调用read()来告知FileChannel向ByteBuffer存储字节,就必须调用缓冲器上的flip(). 让
它做好让别人读取字节的准备(是的,这似乎有一点拙劣,但是请记住,它是很拙劣的,但却
适用于在取最大速度) 如果我们打算使用缓冲器执行进一步的read()操作,我们也必须得调用
clear()来为每个read()做好准备.这在下面这个简单文件复制程序中可以看到:
 
package com.java.io;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel; public class ChannelCopy {
private static final int BSIZE = 1024;
public static void main(String[] args) throws Exception {
if(args.length != 2) {
System.out.println("arguments: sourcefile destfile");
System.exit(1);
}
FileChannel in = new FileInputStream(args[0]).getChannel(),
out = new FileOutputStream(args[1]).getChannel();
ByteBuffer buffer = ByteBuffer.allocate(BSIZE);
while(in.read(buffer) != -1) {
buffer.flip(); // Prepare for writing
out.write(buffer);
buffer.clear(); // Prepare for reading
}
}
}
可以看到,打开~个FileChannel以用于读,而打开另一个以用于写。ByteBuffer被分配了
空间,当FileChannel.read()返回- 1时(一个分界符,毋庸置疑,色源于Unix和C) .表示我们已
经到达了输入的末尾。每次read()操作之后,就会将数据输入到缓冲器中. flip()则是准备缓冲器
以便它的信息可以由write()提取. write()操作之后,信息仍在缓冲器中,接着clear()操作则对所
有的内部指针重新安排,以便缓冲器在另一个read()操作期间能够做好接受数据的准备。
 
然而,上面那个程序并不是处理此类操作的理想方式.特殊方法transferTo()和transferFrom()则允许我们将一个通道和另一个通道直接相连:
package com.java.io;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel; public class TransferTo {
public static void main(String[] args) throws Exception {
if(args.length != 2) {
System.out.println("arguments: sourcefile destfile");
System.exit(1);
}
FileChannel in = new FileInputStream(args[0]).getChannel(),
out = new FileOutputStream(args[1]).getChannel(); in.transferTo(0, in.size(), out);
// Or:
// out.transferFrom(in, 0, in.size());
}
}
1 转换数据          
回过头看GetChannel.java这个程序就会发现,为了输出文件中的信息,我们必须每次只读
取一个字节的数据,然后将每个byte类型强制转换成char类型。这种方法似乎有点原始-一如果
我们查看一下java.nio.CharBuffer这个类,将会发现它有一个toString()方法是这样定义的: "返
回一个包含缓冲器中所有字符的字符串。"既然ByteBuffer可以看作是具有asCharBuffer()方法
的CharBuffer ,那么为什么不用它呢?正如下面的输出语句中第一行所见,这种方法并不能解
决问题:
package com.java.io;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset; public class BufferToText {
private static final int BSIZE = 1024; @SuppressWarnings("resource")
public static void main(String[] args) throws Exception {
FileChannel fc = new FileOutputStream("data2.txt").getChannel();
fc.write(ByteBuffer.wrap("Some text".getBytes()));
fc.close();
fc = new FileInputStream("data2.txt").getChannel();
ByteBuffer buff = ByteBuffer.allocate(BSIZE);
fc.read(buff);
buff.flip();
// Doesn't work:
System.out.println(buff.asCharBuffer()); // Decode using this system's default Charset:
buff.rewind();
String encoding = System.getProperty("file.encoding");
System.out.println("Decoded using " + encoding + ": " + Charset.forName(encoding).decode(buff)); // Or, we could encode with something that will print:
fc = new FileOutputStream("data2.txt").getChannel();
fc.write(ByteBuffer.wrap("Some text".getBytes("UTF-16BE")));
fc.close();
// Now try reading again:
fc = new FileInputStream("data2.txt").getChannel();
buff.clear();
fc.read(buff);
buff.flip();
System.out.println(buff.asCharBuffer()); // Use a CharBuffer to write through:
fc = new FileOutputStream("data2.txt").getChannel();
buff = ByteBuffer.allocate(24); // More than needed
buff.asCharBuffer().put("Some text");
fc.write(buff);
fc.close(); // Read and display:
fc = new FileInputStream("data2.txt").getChannel();
buff.clear();
fc.read(buff);
buff.flip();
System.out.println(buff.asCharBuffer());
}
}
缓冲器容纳的是普通的字节,为了把它们转换成字符,我们要么在输入它们的时候对其进
行编码(这样,它们输出时才具有意义) .要么在将其从缓冲器输出时对它们进行解码。可以使
用java.nio.charset.Charset类实现这些功能,该类提供了把数据编码成多种不同类型的字符集的
工具
 
 

---------------

ThinkJava-新IO的更多相关文章

  1. java 21 - 15 新IO流 NIO

    1:JDK4  新IO要了解的类 Buffer(缓冲),Channer(通道) 2:JDK7  要了解的新IO类 Path:与平台无关的路径. Paths:包含了返回Path的静态方法. public ...

  2. Java 新IO

       NIO提供全新的底层I/O模型.与最初的java.io包中面向流(stream-oriented)概念不同,NIO采用了面向块的概念(block-oriented).在尽可能的情况下,I/O的操 ...

  3. JAVA(六)数据库/网络编程/新IO

    成鹏致远 | lcw.cnblog.com |2014-02-05 数据库 1.JDBC概述 JDBC(Java Database Connectivity,Java数据库连接)提供了一种与平台无关的 ...

  4. Java -- 新IO -- 目录

    20.1 Java 新IO简介 20.2 缓冲区与Buffer 例:演示缓冲区的操作流程 Class : IntBufferDemo01 20.2.2 深入缓冲区操作 20.2.3 创建子缓冲区 20 ...

  5. Pipelines - .NET中的新IO API指引(三) 边看边记

    Pipelines - .NET中的新IO API指引 作者 marcgravell  原文 此系列前两篇网上已有的译文 Pipelines - .NET中的新IO API指引(一) Pipeline ...

  6. Java 8特性尝鲜:新新IO

    Java 8特性尝鲜:新新IO 在这个专题前面的文章中,我们已经看到,使用Java8的lambda表达式对现有的JDK1.2 I/O库的提升,主要是可以使用lambda表达式来构造java.io.Fi ...

  7. Pipelines - .NET中的新IO API指引(一)

    https://zhuanlan.zhihu.com/p/39223648 原文:Pipelines - a guided tour of the new IO API in .NET, part 1 ...

  8. Java——新IO 通道

    import java.io.File; import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.nio.ch ...

  9. 新IO建立的聊天程序

    服务端: package com.net.scday3; import java.io.IOException; import java.net.InetSocketAddress; import j ...

  10. java 1.7 新io 实践 NIO2

    Files 类使用 package com.xinyu.test; import java.io.IOException; import java.nio.ByteBuffer; import jav ...

随机推荐

  1. PHP中__autoload()与spl_autoload_register()函数的用法与区别

    _autoload() 函数在PHP文档中的解释是试图使用尚未被定义的类时自动调用.通过调用此函数,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类. 如何理解这句话,我们首先看下面一个简单 ...

  2. Splay树学习

    首先给出一论文讲的很好: http://www.docin.com/p-63165342.html http://www.docin.com/p-62465596.html 然后给出模板胡浩大神的模板 ...

  3. class []的用法

    span[class='test']    =>匹配所有带有class类名test的span标签 span[class *='test']  =>匹配所有包含了test字符串的class类 ...

  4. python 列表求和

    def sum_list(items): sum_numbers = for x in items: sum_numbers += x return sum_numbers print(sum_lis ...

  5. vim 安装molokai主题

    在.vim文件夹下创建文件夹colors 进入 https://github.com/tomasr/molokai 下载molokai.vim 将其放入colors文件夹下 进入.vimrc中 添加 ...

  6. 史上最强大的40多个纯CSS绘制的图形[转]

    今天在国外的网站上看到了很多看似简单却又非常强大的纯CSS绘制的图形,里面有最简单的矩形.圆形和三角形,也有各种常见的多边形,甚至是阴阳太极和网站小图标,真的非常强大,分享给大家. Square(正方 ...

  7. 谈谈刚接触sea.js框架得看法

    向大神致敬,也是我接触框架得开始. 感谢张鑫旭大神,专业!致敬~   sea.js的7个API,都在下面得链接中有详细说明: http://www.zhangxinxu.com/sp/seajs/do ...

  8. TinyURL

    2018-03-09 15:19:04 TinyURL,短地址,或者叫短链接,指的是一种互联网上的技术与服务.此服务可以提供一个非常短小的URL以代替原来的可能较长的URL,将长的URL地址缩短. 用 ...

  9. 2018-2019-2 网络对抗技术 20165332 Exp2 后门原理与实践

    2018-2019-2 网络对抗技术 20165332 Exp2 后门原理与实践 - 实验内容 任务一:使用netcat获取主机操作Shell,cron启动 任务二:使用socat获取主机操作Shel ...

  10. php--------网页开发实现微信JS的(定位,地图显示,照片选择功能)

    今天说说微信网页开发中一下JS的功能,分享一下,希望对各位有所帮助. 前提:要有公众号,和通过微信认证,绑定域名,得到相应信息,appid,appsecret等. 微信开发文档:https://mp. ...