解读IO复制大文件

开篇几个问题:

你所知道的IO的内容有哪些?假设给你一个任务快速复制大文件甚至是超大文件,你怎么应对?你用什么技术实现?在巨多无比及其变态的用户下载这个文件的时候,你怎么解决这个问题?

 

如果你还不能回答完整第一个问题,那么即使你学了N久,那你也还没有入门。假设你能回答第二个问题你基础还行,假设你能回答并且能实现第三个和第四个问题你就是已经比较强大了。

 

作为一个常用的IO技术---通道技术,很多人都不甚了解,尤其是那些初学者认为IO及其简单。

今天写这篇文章的目的很明确,就是很大家分享一种高层的IO技术---通道技术。

在大家看过的视频甚至很多书上对这个没有怎么涉及,网上的资料也不是很多,更不用说可用了,所以有必要在此和大家分享。

 

 

第一步:在网上找关于通道的文章(注意搜索的技巧否则你找不到这方面的答案,只能看到N多人问的问题),了解一下IO通道的基本原理。

第二步: 扎实你的面相对象思想。

第三步:且看以下源码:

 

package cn.ccsu.cooole.util;

 

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.FileOutputStream;

import java.nio.ByteBuffer;

import java.nio.channels.FileChannel;

/**

 *

 * @author CoolPrince

 *

 * 描述读取大的流文件这个类利用的是通道的技术

 * 测试的时的赋值速度大概是6M/s;(这个根据具体的机器而定)

 *

 */

public class ChannelCopy {

   //设置缓冲区的大小

    private static final int BSIZE = 1024;

   

    /**

     *

     * @param fileFrom :要被复制文件全限名

     * @param fileTo :要复制到目的地的文件全限名

     * @return boolean 返回复制成功与否的信息

     *

     */

    @SuppressWarnings("finally")

    public static boolean copyFile(String fileFrom, String fileTo) throws FileNotFoundException,IOException{

       boolean flag = true;//初始化返回文件复制成功与否的信息标志

       File file = new File(fileFrom); //源文件名

        FileChannel in = null, out = null; //通道初始化

       try {

           in = new FileInputStream(file).getChannel(); //获取文件通道

           out = new FileOutputStream(new File(fileTo)).getChannel();     //  得到输出流的通道       

       } catch (FileNotFoundException e) {

           flag = false;//此时文件没有找到故将此设置为false

           throw new FileNotFoundException(e.getMessage());    

       }     

        try {

            ByteBuffer buff  = ByteBuffer.allocate(BSIZE); //分配缓冲区的大小

              while(in.read(buff) != -1){ //一直读到文件的结尾的地方

                   buff.flip();//将缓冲区的内容倒出来

                   out.write(buff);//将缓冲区的内容直接写到目标文件中

                   buff.clear();//清除缓冲区的内容

               }    

              in.close();//关闭输入流

           } catch (IOException e) {

              flag = false;

              throw new IOException(e);

           }

       return flag;

      

    }

    /**

     * 第二种方式对copyFile进行重载 一适应用户传入文件时的情况

     * 使其更为通用

     * 具体解释参考上面的内容

     * @param fileFrom :要被复制文件

     * @param fileTo :要复制到目的地的文件

     * @return boolean 返回复制成功与否的信息

     *

     */

    @SuppressWarnings("finally")

    public static boolean copyFile(File fileFrom,File fileTo) throws FileNotFoundException,IOException{

       boolean flag = true;    

        FileChannel fc = null, out = null;

       try {

           fc = new FileInputStream(fileFrom).getChannel();

           out = new FileOutputStream(fileTo).getChannel();

          

       } catch (FileNotFoundException e) {

           flag = false;

           throw new FileNotFoundException(e.getMessage());    

       }  

       ByteBuffer buff  = ByteBuffer.allocate(BSIZE);

         try {

           while(fc.read(buff) != -1){

               buff.flip();

               out.write(buff);

               buff.clear();

            }    

           out.close();

           fc.close();

       } catch (IOException e1) {

           flag = false;

           throw new IOException(e1);

       }

          return flag;                

    }

    /**

     *

     * 直接将一个通道和另一个通道进行相连

     * 这里是从fileFromfileTo 利用tansferTo进行拷贝

     * 被拷贝的是fileFrom,新的文件是fileTo

     * @param fileFrom

     * @param fileTo

     * @return boolean

     * @throws FileNotFoundException

     * @throws IOException

     */

    public static boolean tansferTocopyFile(File fileFrom,File fileTo) throws FileNotFoundException,IOException{

       boolean flag = true;    

        FileChannel fc = null, out = null;    

           try {

              fc = new FileInputStream(fileFrom).getChannel();

              out = new FileOutputStream(fileTo).getChannel();

             

           } catch (FileNotFoundException e) {

                flag = false;

                throw new FileNotFoundException(e.getMessage());

           }  

           try {

              fc.transferTo(0,fc.size(),out);

           } catch (IOException e1) {

              flag = false;

              throw new IOException(e1);

           }

          return flag;                

    }

    /**第二种方式对tansferTocopyFile进行重载 一适应用户传入文件时的情况

     * 使其更为通用

     * 直接将一个通道和另一个通道进行相连

     * 这里是从fileTofileFrom 利用tansferFrom进行拷贝

     * 被拷贝的是fileFrom,新的文件是fileTo

     * 具体解释参考上面的内容

     * @param fileFrom

     * @param fileTo

     * @return boolean

     * @throws FileNotFoundException

     * @throws IOException

     */

    public static boolean tansferFromcopyFile(File fileFrom,File fileTo) throws FileNotFoundException,IOException{

       boolean flag = true;    

        FileChannel fc = null, out = null;    

           try {

              fc = new FileInputStream(fileFrom).getChannel();

              out = new FileOutputStream(fileTo).getChannel();

             

           } catch (FileNotFoundException e) {

                flag = false;

                throw new FileNotFoundException(e.getMessage());

           }  

           try {

              out.transferFrom(fc,0,fc.size());

           } catch (IOException e1) {

              flag = false;

              throw new IOException(e1);

           }

          return flag;                

    }

}

第四步:自己将其实现 并写成多线程的 慢慢体会

第五步:看下下面的这篇文章(浅析学习技术的误区http://hi.baidu.com/voyage_mh/blog/item/933f2407b6565c7303088161.html)或许对你有所帮助,无论是学习技术的还是做其他事的。限于博客的篇幅限制,以及时间紧张的关系我也就此驻笔,希望对你有所帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值