`
iavere
  • 浏览: 10588 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

解读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;                

    }

    /**

     *

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

     * 这里是从fileFrom到fileTo 利用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进行重载 一适应用户传入文件时的情况

     * 使其更为通用

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

     * 这里是从fileTo到fileFrom 利用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)或许对你有所帮助,无论是学习技术的还是做其他事的。限于博客的篇幅限制,以及时间紧张的关系我也就此驻笔,希望对你有所帮助。


<转>
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics