NIO相关的类都放在了Java.nio包下,他的功能比较强大的。NIO使用了不同的方式(内存映射文件)来处理输入和输出,也就是说NIO将文件或文件的一段区域映射到内存中,这样子就可以象访问内存一样访问文件了。
Buffer就是一个数组。他的作用就是装入数据和输出数据。Buffer有2个重要的方法:flip(从Buffer中取出数据)和clear(向Buffer中放入数据)
Channel可以直接将指定文件的部分或者全部直接映射成buffer。程序也不能直接和Channel来交互数据,包括读和写,都要经过Buffer这个中间的东西才可以。
import java.nio.*; public class BufferTest { public static void main(String[] args) { // 创建Buffer CharBuffer buff = CharBuffer.allocate(8); //① System.out.println("capacity: " + buff.capacity()); System.out.println("limit: " + buff.limit()); System.out.println("position: " + buff.position()); // 放入元素 buff.put('a'); buff.put('b'); buff.put('c'); //② System.out.println("加入三个元素后,position = " + buff.position()); // 调用flip()方法 buff.flip(); //③ System.out.println("执行flip()后,limit = " + buff.limit()); System.out.println("position = " + buff.position()); // 取出第一个元素 System.out.println("第一个元素(position=0):" + buff.get()); // ④ System.out.println("取出一个元素后,position = " + buff.position()); // 调用clear方法 buff.clear(); //⑤ System.out.println("执行clear()后,limit = " + buff.limit()); System.out.println("执行clear()后,position = " + buff.position()); System.out.println("执行clear()后,缓冲区内容并没有被清除:" + "第三个元素为:" + buff.get(2)); // ⑥ System.out.println("执行绝对读取后,position = " + buff.position()); } }
import java.io.*; import java.nio.*; import java.nio.channels.*; import java.nio.charset.*; public class FileChannelTest { public static void main(String[] args) { File f = new File("FileChannelTest.java"); try( // 创建FileInputStream,以该文件输入流创建FileChannel FileChannel inChannel = new FileInputStream(f).getChannel(); // 以文件输出流创建FileBuffer,用以控制输出 FileChannel outChannel = new FileOutputStream("a.txt") .getChannel()) { // 将FileChannel里的全部数据映射成ByteBuffer MappedByteBuffer buffer = inChannel.map(FileChannel .MapMode.READ_ONLY , 0 , f.length()); // ① // 使用GBK的字符集来创建解码器 Charset charset = Charset.forName("GBK"); // 直接将buffer里的数据全部输出 outChannel.write(buffer); // ② // 再次调用buffer的clear()方法,复原limit、position的位置 buffer.clear(); // 创建解码器(CharsetDecoder)对象 CharsetDecoder decoder = charset.newDecoder(); // 使用解码器将ByteBuffer转换成CharBuffer CharBuffer charBuffer = decoder.decode(buffer); // CharBuffer的toString方法可以获取对应的字符串 System.out.println(charBuffer); } catch (IOException ex) { ex.printStackTrace(); } } }
import java.io.*; import java.nio.*; import java.nio.channels.*; public class RandomFileChannelTest { public static void main(String[] args) throws IOException { File f = new File("a.txt"); try( // 创建一个RandomAccessFile对象 RandomAccessFile raf = new RandomAccessFile(f, "rw"); // 获取RandomAccessFile对应的Channel FileChannel randomChannel = raf.getChannel()) { // 将Channel中所有数据映射成ByteBuffer ByteBuffer buffer = randomChannel.map(FileChannel .MapMode.READ_ONLY, 0 , f.length()); // 把Channel的记录指针移动到最后 randomChannel.position(f.length()); // 将buffer中所有数据输出 randomChannel.write(buffer); } } }
import java.io.*; import java.nio.*; import java.nio.channels.*; import java.nio.charset.*; public class ReadFile { public static void main(String[] args) throws IOException { try( // 创建文件输入流 FileInputStream fis = new FileInputStream("ReadFile.java"); // 创建一个FileChannel FileChannel fcin = fis.getChannel()) { // 定义一个ByteBuffer对象,用于重复取水 ByteBuffer bbuff = ByteBuffer.allocate(64); // 将FileChannel中数据放入ByteBuffer中 while( fcin.read(bbuff) != -1 ) { // 锁定Buffer的空白区 bbuff.flip(); // 创建Charset对象 Charset charset = Charset.forName("GBK"); // 创建解码器(CharsetDecoder)对象 CharsetDecoder decoder = charset.newDecoder(); // 将ByteBuffer的内容转码 CharBuffer cbuff = decoder.decode(bbuff); System.out.print(cbuff); // 将Buffer初始化,为下一次读取数据做准备 bbuff.clear(); } } } }
编码和解码: 我们在玩j2ee的时候经常要最数据做编码和解码,因为要前后台交互数据,这里的编码和解码主要是说我们在使用NIO的时候对文件做读写操作时用来的编码和解码。编码就是把明文的字符串序列转换成计算机理解的字节序列,解码就是把字节序列转化成普通人能看得懂的明文字符串。 对于我来说使用最大的就2种字符串集,一个是GBK(简体中文字符集)一个是UTF-8(8位的UCS转化格式)。
import java.nio.charset.*; import java.util.*; public class CharsetTest { public static void main(String[] args) { // 获取Java支持的全部字符集 SortedMap<String,Charset> map = Charset.availableCharsets(); for (String alias : map.keySet()) { // 输出字符集的别名和对应的Charset对象 System.out.println(alias + "----->" + map.get(alias)); } } }
import java.nio.*; import java.nio.charset.*; public class CharsetTransform { public static void main(String[] args) throws Exception { // 创建简体中文对应的Charset Charset cn = Charset.forName("GBK"); // 获取cn对象对应的编码器和解码器 CharsetEncoder cnEncoder = cn.newEncoder(); CharsetDecoder cnDecoder = cn.newDecoder(); // 创建一个CharBuffer对象 CharBuffer cbuff = CharBuffer.allocate(8); cbuff.put('孙'); cbuff.put('悟'); cbuff.put('空'); cbuff.flip(); // 将CharBuffer中的字符序列转换成字节序列 ByteBuffer bbuff = cnEncoder.encode(cbuff); // 循环访问ByteBuffer中的每个字节 for (int i = 0; i < bbuff.capacity() ; i++) { System.out.print(bbuff.get(i) + " "); } // 将ByteBuffer的数据解码成字符序列 System.out.println("\n" + cnDecoder.decode(bbuff)); } }
文件锁在操作系统上是很平常的事情,使用文件锁可以有效的阻止多个进程并发修改同一个文件。其实和数据库的锁是差不多的。
import java.io.*; import java.nio.*; import java.nio.channels.*; public class FileLockTest { public static void main(String[] args) throws Exception { try( // 使用FileOutputStream获取FileChannel FileChannel channel = new FileOutputStream("a.txt") .getChannel()) { // 使用非阻塞式方式对指定文件加锁 FileLock lock = channel.tryLock(); // 程序暂停10s Thread.sleep(10000); // 释放锁 lock.release(); } } }
原文地址:http://blog.csdn.net/u011794238/article/details/42294899