java NIO 使用实例

来源:互联网 发布:百年孤独 知乎 编辑:程序博客网 时间:2024/06/08 08:04

实现一:使用nio实现文件复制

[java] view plaincopyprint?
  1. package study.nio;  
  2. import java.io.File;  
  3. import java.io.FileInputStream;  
  4. import java.io.FileOutputStream;  
  5. import java.io.FileNotFoundException;  
  6. import java.io.IOException;  
  7. import java.nio.channels.FileChannel;  
  8. import java.nio.ByteBuffer;  
  9. public class TestCopyFile {  
  10.     public static void main(String[] args) throws IOException {  
  11.         //调用FileManager类的copyFile静态方法  
  12.         FileManager.copyFile(new File("src.txt"), new File("dst.txt"));  
  13.     }  
  14. }  
  15. class FileManager {  
  16.     //把可能出现的异常抛给上层调用者处理  
  17.     public static void copyFile(File src, File dst)   
  18.             throws FileNotFoundException, IOException {  
  19.         //得到一个源文件对应的输入通道  
  20.         FileChannel fcin = new FileInputStream(src).getChannel();  
  21.         //得到一个目标文件对应的输出通道  
  22.         FileChannel fcout = new FileOutputStream(dst).getChannel();  
  23.         //生成一个1024字节的ByteBuffer实例  
  24.         ByteBuffer buf = ByteBuffer.allocate(1024);  
  25.         while(fcin.read(buf) != -1) {  
  26.             buf.flip();     //准备写  
  27.             fcout.write(buf);  
  28.             buf.clear();        //准备读  
  29.         }  
  30.     }  
  31.       
  32. }  

还可以使用下面方式进行操作,在FileChannel中有两个特殊方法可以允许我们直接将两个通道相连:

long transferFrom(ReadableByteChannel src, long position, long count);

long transferTo(long position, long count, WriteableByteChannel targets);

上面while循环可以替换为:

fcin.transferTo(0, fcin.size(), fcout); 或者 fcout.transferFrom(fcin, 0, fcin.size());

 

实现二:向一个空文件中写入some text,再以只读方式打开该文件,在尾部追加some more,最终将该文件内容输出。

[java] view plaincopyprint?
  1. package study.nio;  
  2. import java.io.File;  
  3. import java.io.FileInputStream;  
  4. import java.io.FileOutputStream;  
  5. import java.io.RandomAccessFile;  
  6. import java.nio.ByteBuffer;  
  7. import java.nio.channels.FileChannel;  
  8.   
  9. public class GetChannel {  
  10.     //为了使代码明晰,暂不处理异常  
  11.     public static void main(String[] args) throws Exception {  
  12.         FileChannel fc = null;  
  13.         //向一个文件中写入文本  
  14.         fc = new FileOutputStream(new File("data.txt")).getChannel();  
  15.         fc.write(ByteBuffer.wrap("some text".getBytes()));  
  16.         fc.close();  
  17.         //以读写方式打开文件,并在尾部追加内容  
  18.         fc = new RandomAccessFile("data.txt""rw").getChannel();  
  19.         fc.position(fc.size());  
  20.         fc.write(ByteBuffer.wrap("some more".getBytes()));  
  21.         fc.close();  
  22.         //将文件里的内容读出来  
  23.         fc = new FileInputStream("data.txt").getChannel();  
  24.         ByteBuffer buf = ByteBuffer.allocate(1024);  
  25.         fc.read(buf);  
  26.         buf.flip();  
  27.         while(buf.hasRemaining()) {  
  28.             System.out.print((char)buf.get());  
  29.         }         
  30.     }  
  31. }  


 

以上均使用的是字节操作流,与nio相一致。Reader和Writer这些字符模式类不能用于产生通道,但是java.nio.channels.Channels类中提供了实用方法,可以在通道中产生Reader和Writer。

       Channels.newReader();

       Channels.newWriter();

实现三:将一个大文件映射到内存并查找指定的文本内容是否在该文件中(曾记得李开复与微软的故事,当然李开复是从邮件中查找信息,并且邮件被截成了图片,⊙﹏⊙b汗)

 

[java] view plaincopyprint?
  1. public class LargeMappedFiles {  
  2.     public static void main(String args[]) {     
  3.         try {  
  4.             File[] files = new File[] {new File("src1.txt"), new File("src2.txt")};   
  5.           ArrayList<String> ls = search(files, "something is wrong");  
  6.           for(int i=0; i<ls.size(); i++) {  
  7.             System.out.println(ls.get(i));  
  8.           }  
  9.         } catch (FileNotFoundException e) {     
  10.             e.printStackTrace();     
  11.         } catch (Exception e) {     
  12.             e.printStackTrace();     
  13.         }     
  14.     }  
  15.     //实现简单的内容检索  
  16.     private static ArrayList<String> search(File[] files, String text) throws Exception {  
  17.         //把检索结果放到一个list中  
  18.         ArrayList<String> result = new ArrayList<String>();  
  19.         //循环遍历文件  
  20.         for(File src : files) {  
  21.             //将整个文件映射到内存  
  22.             MappedByteBuffer dst = new RandomAccessFile(src, "rw")  
  23.             .getChannel()     
  24.             .map(FileChannel.MapMode.READ_WRITE, 0, src.length());  
  25.         //对字符进行解码  
  26.         String str = Charset.forName("UTF-8").decode(dst).toString();  
  27.         //准备进行读  
  28.         dst.flip();  
  29.         if(str.indexOf(text) != -1) {  
  30.             result.add(src.getName());  
  31.         }  
  32.         //准备写  
  33.         dst.clear();  
  34.         }  
  35.         return result;  
  36.     }  
  37. }  


 

实现四:在前面的学习中了解到nio为所有原始数据类型提供了Buffer支持,并且在ByteBuffer中实现了asXBuffer()方法直接将一个ByteBuffer转换成其它类型的Buffer。本例实现数据类型的转换。

[java] view plaincopyprint?
  1. import java.nio.IntBuffer;  
  2. import java.nio.FloatBuffer;  
  3. import java.nio.ByteBuffer;  
  4. import java.util.Arrays;  
  5.   
  6. public class CastBuffer {  
  7.     static byte[] bytes = new byte[] {012345'a''b''c'};  
  8.           
  9.     public static void main(String[] args) {  
  10.         ByteBuffer bBuf = ByteBuffer.wrap(bytes);  
  11.         System.out.println(Arrays.toString(bBuf.array()));  
  12.         //转换成IntBuffer  
  13.         IntBuffer iBuf = ((ByteBuffer)bBuf.rewind()).asIntBuffer();  
  14.         while(iBuf.hasRemaining()) {  
  15.             System.out.print(iBuf.get()+",");  
  16.         }  
  17.         //转换成FloatBuffer  
  18.         FloatBuffer fBuf = ((ByteBuffer)bBuf.rewind()).asFloatBuffer();  
  19.         while(fBuf.hasRemaining()) {  
  20.             System.out.print(fBuf.get()+",");  
  21.         }  
  22.     }  
  23. }  

原创粉丝点击