Java nio 学习笔记(三)

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

package study.nio;  
import java.io.File;  
import java.io.FileInputStream;  
import java.io.FileOutputStream;  
import java.io.FileNotFoundException;  
import java.io.IOException;  
import java.nio.channels.FileChannel;  
import java.nio.ByteBuffer;  
public class TestCopyFile {  
    public static void main(String[] args) throws IOException {  
        //调用FileManager类的copyFile静态方法  
        FileManager.copyFile(new File("src.txt"), new File("dst.txt"));  
    }  
}  
class FileManager {  
    //把可能出现的异常抛给上层调用者处理  
    public static void copyFile(File src, File dst)   
            throws FileNotFoundException, IOException {  
        //得到一个源文件对应的输入通道  
        FileChannel fcin = new FileInputStream(src).getChannel();  
        //得到一个目标文件对应的输出通道  
        FileChannel fcout = new FileOutputStream(dst).getChannel();  
        //生成一个1024字节的ByteBuffer实例  
        ByteBuffer buf = ByteBuffer.allocate(1024);  
        while(fcin.read(buf) != -1) {  
            buf.flip();     //准备写  
            fcout.write(buf);  
            buf.clear();        //准备读  
        }  
    }  
      
}  


还可以使用下面方式进行操作,在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,最终将该文件内容输出。

package study.nio;  
import java.io.File;  
import java.io.FileInputStream;  
import java.io.FileOutputStream;  
import java.io.RandomAccessFile;  
import java.nio.ByteBuffer;  
import java.nio.channels.FileChannel;  
  
public class GetChannel {  
    //为了使代码明晰,暂不处理异常  
    public static void main(String[] args) throws Exception {  
        FileChannel fc = null;  
        //向一个文件中写入文本  
        fc = new FileOutputStream(new File("data.txt")).getChannel();  
        fc.write(ByteBuffer.wrap("some text".getBytes()));  
        fc.close();  
        //以读写方式打开文件,并在尾部追加内容  
        fc = new RandomAccessFile("data.txt", "rw").getChannel();  
        fc.position(fc.size());  
        fc.write(ByteBuffer.wrap("some more".getBytes()));  
        fc.close();  
        //将文件里的内容读出来  
        fc = new FileInputStream("data.txt").getChannel();  
        ByteBuffer buf = ByteBuffer.allocate(1024);  
        fc.read(buf);  
        buf.flip();  
        while(buf.hasRemaining()) {  
            System.out.print((char)buf.get());  
        }         
    }  
}  

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

       Channels.newReader();

       Channels.newWriter();

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

public class LargeMappedFiles {  
    public static void main(String args[]) {     
        try {  
            File[] files = new File[] {new File("src1.txt"), new File("src2.txt")};   
          ArrayList<String> ls = search(files, "something is wrong");  
          for(int i=0; i<ls.size(); i++) {  
            System.out.println(ls.get(i));  
          }  
        } catch (FileNotFoundException e) {     
            e.printStackTrace();     
        } catch (Exception e) {     
            e.printStackTrace();     
        }     
    }  
    //实现简单的内容检索  
    private static ArrayList<String> search(File[] files, String text) throws Exception {  
        //把检索结果放到一个list中  
        ArrayList<String> result = new ArrayList<String>();  
        //循环遍历文件  
        for(File src : files) {  
            //将整个文件映射到内存  
            MappedByteBuffer dst = new RandomAccessFile(src, "rw")  
            .getChannel()     
            .map(FileChannel.MapMode.READ_WRITE, 0, src.length());  
        //对字符进行解码  
        String str = Charset.forName("UTF-8").decode(dst).toString();  
        //准备进行读  
        dst.flip();  
        if(str.indexOf(text) != -1) {  
            result.add(src.getName());  
        }  
        //准备写  
        dst.clear();  
        }  
        return result;  
    }  
}  

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

import java.nio.IntBuffer;  
import java.nio.FloatBuffer;  
import java.nio.ByteBuffer;  
import java.util.Arrays;  
  
public class CastBuffer {  
    static byte[] bytes = new byte[] {0, 1, 2, 3, 4, 5, 'a', 'b', 'c'};  
          
    public static void main(String[] args) {  
        ByteBuffer bBuf = ByteBuffer.wrap(bytes);  
        System.out.println(Arrays.toString(bBuf.array()));  
        //转换成IntBuffer  
        IntBuffer iBuf = ((ByteBuffer)bBuf.rewind()).asIntBuffer();  
        while(iBuf.hasRemaining()) {  
            System.out.print(iBuf.get()+",");  
        }  
        //转换成FloatBuffer  
        FloatBuffer fBuf = ((ByteBuffer)bBuf.rewind()).asFloatBuffer();  
        while(fBuf.hasRemaining()) {  
            System.out.print(fBuf.get()+",");  
        }  
    }  
}  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值