zoukankan      html  css  js  c++  java
  • 利用JAVA获取远程文件及使用断点续传 供学习者使用

    闲来没事,就做做,程序还是要多写才好@

    原理不说,文件方面及I/O方面,去BAIDU一下就知道,断点续传的原理也很简单,就是在原来已经下载的基础之上继续下载就可以了,用到了这么关键的一句:urlc.setRequestProperty("RANGE", "bytes="+fileSize+"-"); 其它就应该很简单吧.

    /**
     * 文件传送客户端:获取远程文件,并采用断点续传原理
     * 软件很简单,写这个东东经历了三个步子:
     * 1、写了一个文件传送程序,基于客户端与服务端
     * 2、写了一个从网上获取文件的程序,学了怎么样使用:HttpURLConnection及URL
     * 3、就是现在这个程序,在2的基础之上加上了断点续传的原理。
     * 不过,功能虽然是达到了,不过,里面还有很多不如意的地方,慢慢改进吧,特别是效率方面
     * 如果有实际需要,可以把这个改成线程的,很简单了哦。
     * 准备做第四个版本:多线程文件下载。
     */

    import java.io.BufferedInputStream;
    import java.io.DataOutputStream;
    import java.io.File;
    import java.io.FileOutputStream;

    import java.io.IOException;

    import java.io.RandomAccessFile;

    import java.net.*;

    /**
     * 文件传送客户端:获取远程文件
     */
    public class GetRemoteFile_Client_GoOn
    {
      public GetRemoteFile_Client_GoOn()
      {
      }

      private boolean FileExist(String pathAndFile)//确定文件是否已经下载,但没有下载完成
      {
        File file = new File(pathAndFile);
        if (file.exists())
          return true;
        else
          return false;
      }

      private long FileSize(String pathAndFile)//确定已经下载了的文件大小
      {
        File file = new File(pathAndFile);
        return file.length();
      }
      private void FileRename(String fName,String nName)//将下载完全的文件更名,去掉.tp名
      {
        File file = new File(fName);
        file.renameTo(new File(nName));
        file.delete();
      }
      public static void main(String[] args)
      {
        URL url = null;
        HttpURLConnection urlc = null;
        DataOutputStream dos = null;
        BufferedInputStream bis = null;
        FileOutputStream fos = null;
        String localFile = "d://x.x";//文件保存的地方及文件名,具体情况可以改
        String localFile_bak = localFile + ".tp";//未下载完文件加.tp扩展名,以便于区别
        GetRemoteFile_Client_GoOn gco = new GetRemoteFile_Client_GoOn();
        long fileSize = 0;
        long start = System.currentTimeMillis();
        int len = 0;
        byte[] bt = new byte[1024];
        //byte[] buffer=new byte[50*1024];
        RandomAccessFile raFile=null;
        long TotalSize=0;//要下载的文件总大小
        try
        {
          url = new URL("http://www.netbox.cn/download/nbsetup.EXE");     
          urlc = (HttpURLConnection) url.openConnection();
          TotalSize=Long.parseLong(urlc.getHeaderField("Content-Length"));
          System.out.println("下载文件大小为:"+TotalSize);
          urlc.disconnect();//先断开,下面再连接,否则下面会报已经连接的错误
          urlc = (HttpURLConnection) url.openConnection();
          //确定文件是否存在
          if (gco.FileExist(localFile_bak))//采用断点续传,这里的依据是看下载文件是否在本地有.tp有扩展名同名文件
          {
            System.out.println("文件续传中...");
            fileSize = gco.FileSize(localFile_bak); //取得文件在小,以便确定随机写入的位置
            System.out.println("fileSize:"+fileSize);
            //设置User-Agent
            //urlc.setRequestProperty("User-Agent","NetFox");
            //设置断点续传的开始位置
            urlc.setRequestProperty("RANGE", "bytes="+fileSize+"-");
            //urlc.setRequestProperty("RANGE", "bytes="+fileSize);//这样写不行,不能少了这个"-".
            //设置接受信息
            urlc.setRequestProperty("Accept","image/gif,image/x-xbitmap,application/msword,*/*");       
            raFile=new RandomAccessFile(localFile_bak,"rw");//随机方位读取
            raFile.seek(fileSize);//定位指针到fileSize位置
            bis = new BufferedInputStream(urlc.getInputStream());
            while ((len = bis.read(bt)) > 0)//循环获取文件
            {
              raFile.write(bt, 0, len);
              //buffer=buffer+bt;
              //System.
            }
            System.out.println("文件续传接收完毕!");       
          }
          else//采用原始下载
          {
            fos = new FileOutputStream(localFile_bak); //没有下载完毕就将文件的扩展名命名.bak
            dos = new DataOutputStream(fos);
            bis = new BufferedInputStream(urlc.getInputStream());       
            System.out.println("正在接收文件...");
            int test=0;
            while ((len = bis.read(bt)) > 0)//循环获取文件
            {
              dos.write(bt, 0, len);
              test++;
              if(test==50)//这里是测试,你可以删除这里,就可以正常下载了
                break;
            }       
            //System.out.println("文件正常接收完毕!");
          }     
          System.out.println("共用时:" +
                             (System.currentTimeMillis() - start) / 1000);
          if(bis!=null)
            bis.close();
          if(dos!=null)
            dos.close();
          if(fos!=null)
            fos.close();
          if(raFile!=null)
            raFile.close();
          System.out.println("localFile_bak:"+gco.FileSize(localFile_bak));
          if(gco.FileSize(localFile_bak)==TotalSize)//下载完毕后,将文件重命名
          {
            gco.FileRename(localFile_bak,localFile);
          }
          System.exit(0);
        }
        catch (Exception e)
        {
          try
          {
            if(bis!=null)
              bis.close();
            if(dos!=null)
              dos.close();
            if(fos!=null)
              fos.close();
            if(raFile!=null)
              raFile.close();
          }
          catch (IOException f)
          {
            f.printStackTrace();
          }
          e.printStackTrace();
        }
        System.exit(0);
      }

    再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

  • 相关阅读:
    JS运算符之void
    JS的常用事件
    JS中的数据类型
    企业如何搭建管理驾驶舱
    项目启动会必须汇报的26个要素
    想要读懂大数据,你不得不先掌握这些核心技术
    关于oracle数据库中读取文件路径的问题整理
    文档:用博客做技术文档的总结
    Kettle 作业(Job)和 转换(Transform)
    子网划分很难?10分钟教会你口算子网划分!又快又准!
  • 原文地址:https://www.cnblogs.com/skiwdhwhssh/p/10342218.html
Copyright © 2011-2022 走看看