`
gaoyuntao2005
  • 浏览: 311214 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JAVA断点续传(B/S)(1)

阅读更多

说明:

SiteFileFetch.java 负责整个文件的抓取,控制内部线程(FileSplitterFetch类)。  
FileSplitterFetch.java 负责部分文件的抓取。  
FileAccess.java 负责文件的存储。  
SiteInfoBean.java 要抓取的文件的信息,如文件保存的目录,名字,抓取文件的URL等。  
Utility.java 工具类,放一些简单的方法。

*
 **SiteFileFetch.java
 */
package NetFox;

import java.io.*;
import java.net.*;

public class SiteFileFetch extends Thread {
    SiteInfoBean siteInfoBean = null; // 文件信息Bean
    long[] nStartPos; // 开始位置
    long[] nEndPos; // 结束位置
    FileSplitterFetch[] fileSplitterFetch; // 子线程对象
    long nFileLength; // 文件长度
    boolean bFirst = true; // 是否第一次取文件
    boolean bStop = false; // 停止标志
    File tmpFile; // 文件下载的临时信息
    DataOutputStream output; // 输出到文件的输出流
    
    public SiteFileFetch(SiteInfoBean bean) throws IOException {
        siteInfoBean = bean;
        // tmpFile = File.createTempFile ("zhong","1111",new
        // File(bean.getSFilePath()));
        tmpFile = new File(bean.getSFilePath() + File.separator
                + bean.getSFileName() + ".info");
        if (tmpFile.exists()) {
            bFirst = false;
            read_nPos();
        } else {
            nStartPos = new long[bean.getNSplitter()];
            nEndPos = new long[bean.getNSplitter()];
        }
    }

    public void run() {
        // 获得文件长度
        // 分割文件
        // 实例FileSplitterFetch
        // 启动FileSplitterFetch线程
        // 等待子线程返回
        try {
            if (bFirst) {
                nFileLength = getFileSize();
                if (nFileLength == -1) {
                    System.err.println("File Length is not known!");
                } else if (nFileLength == -2) {
                    System.err.println("File is not access!");
                } else {
                    for (int i = 0; i < nStartPos.length; i++) {
                        nStartPos[i] = (long) (i * (nFileLength / nStartPos.length));
                    }
                    for (int i = 0; i < nEndPos.length - 1; i++) {
                        nEndPos[i] = nStartPos[i + 1];
                    }
                    nEndPos[nEndPos.length - 1] = nFileLength;
                }
            }
            // 启动子线程
            fileSplitterFetch = new FileSplitterFetch[nStartPos.length];
            for (int i = 0; i < nStartPos.length; i++) {
                fileSplitterFetch[i] = new FileSplitterFetch(siteInfoBean
                        .getSSiteURL(), siteInfoBean.getSFilePath()
                        + File.separator + siteInfoBean.getSFileName(),
                        nStartPos[i], nEndPos[i], i);
                Utility.log("Thread " + i + " , nStartPos = " + nStartPos[i]
                        + ", nEndPos = " + nEndPos[i]);
                fileSplitterFetch[i].start();
            }
            // fileSplitterFetch[nPos.length-1] = new
            // FileSplitterFetch(siteInfoBean.getSSiteURL(),siteInfoBean.getSFilePath()
            // + File.separator +
            // siteInfoBean.getSFileName(),nPos[nPos.length-1],nFileLength,nPos.length-1);
            // Utility.log("Thread " + (nPos.length-1) + " , nStartPos = " +
            // nPos[nPos.length-1] + ",nEndPos = " + nFileLength);
            // fileSplitterFetch[nPos.length-1].start();
            // 等待子线程结束
            // int count = 0;
            // 是否结束while循环
            boolean breakWhile = false;
            while (!bStop) {
                write_nPos();
                Utility.sleep(500);
                breakWhile = true;
                for (int i = 0; i < nStartPos.length; i++) {
                    if (!fileSplitterFetch[i].bDownOver) {
                        breakWhile = false;
                        break;
                    }
                }
                if (breakWhile)
                    break;
                // count++;
                // if(count>4)
                // siteStop();
            }
            System.err.println("文件下载结束!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    } // 获得文件长度

    public long getFileSize() {
        int nFileLength = -1;
        try {
            URL url = new URL(siteInfoBean.getSSiteURL());
            HttpURLConnection httpConnection = (HttpURLConnection) url
                    .openConnection();
            httpConnection.setRequestProperty("User-Agent", "NetFox");
            int responseCode = httpConnection.getResponseCode();
            if (responseCode >= 400) {
                processErrorCode(responseCode);
                return -2; // -2 represent access is error
            }
            String sHeader;
            for (int i = 1;; i++) {
                // DataInputStream in = new
                // DataInputStream(httpConnection.getInputStream ());
                // Utility.log(in.readLine());
                sHeader = httpConnection.getHeaderFieldKey(i);
                if (sHeader != null) {
                    if (sHeader.equals("Content-Length")) {
                        nFileLength = Integer.parseInt(httpConnection
                                .getHeaderField(sHeader));
                        break;
                    }
                } else
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        Utility.log(nFileLength);
        return nFileLength;
    }

    // 保存下载信息(文件指针位置)
    private void write_nPos() {
        try {
            output = new DataOutputStream(new FileOutputStream(tmpFile));
            output.writeInt(nStartPos.length);
            for (int i = 0; i < nStartPos.length; i++) {
                // output.writeLong(nPos[i]);
                output.writeLong(fileSplitterFetch[i].nStartPos);
                output.writeLong(fileSplitterFetch[i].nEndPos);
            }
            output.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 读取保存的下载信息(文件指针位置)
    private void read_nPos() {
        try {
            DataInputStream input = new DataInputStream(new FileInputStream(
                    tmpFile));
            int nCount = input.readInt();
            nStartPos = new long[nCount];
            nEndPos = new long[nCount];
            for (int i = 0; i < nStartPos.length; i++) {
                nStartPos[i] = input.readLong();
                nEndPos[i] = input.readLong();
            }
            input.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void processErrorCode(int nErrorCode) {
        System.err.println("Error Code : " + nErrorCode);
    }

    // 停止文件下载
    public void siteStop() {
        bStop = true;
        for (int i = 0; i < nStartPos.length; i++)
            fileSplitterFetch[i].splitterStop();
    }
}

 

分享到:
评论

相关推荐

    B/S网盘系统

    6. **性能优化**:由于文件操作可能涉及大量数据,因此系统需要进行性能优化,例如使用分块上传、断点续传、多线程下载等技术,提高用户体验。 7. **分布式设计**:大型的B/S网盘系统往往采用分布式设计,包括...

    java swing开发B站视频下载工具,BiliBili视频下载工具,超好用的B站视频下载工具.zip

    支持断点续传下载 支持CC字幕下载 支持互动视频下载 支持课程视频下载 支持相簿图片下载 开发技术 java swing,java awt 依赖包文件(可选) 链接:https://pan.baidu.com/s/18-zekCttaTwVY52_gA3btg?pwd=oadu ...

    基于Java的下载工具的设计与实现.docx

    为了解决这一问题,提高下载效率和用户体验,本设计提出了一种基于Java语言的下载工具,支持断点续传和多线程下载等功能。 ##### 1.2 系统意义 本设计旨在开发一款高效稳定的下载工具,能够自动处理网络中断导致的...

    JAVA文件传输(论文+源代码)

    需求分析则会列出用户期望的功能,如上传、下载、断点续传等。 系统详细设计部分可能详细列出了各个模块,如用户界面、连接管理、文件处理和错误处理等。FTP协议的介绍可能解释了如何通过Java实现FTP通信,包括登录...

    java 实现下载功能源码

    10. **断点续传**:如果源码支持断点续传,它将保存当前下载的进度,当下载因某种原因中断后,可以从上次停止的地方继续下载,而不是重新开始。 在实际项目中,这样的下载工具可能还会考虑其他因素,如重试机制、...

    [计算机项目]基于java的局域网飞鸽传书系统设计与实现(源代码+项目报告).zip

    7. **未来改进方向**:提出可能的优化方案和未来扩展功能的设想,比如支持断点续传、加密传输等。 通过对这些内容的深入理解和学习,不仅可以掌握Java网络编程的基本技能,还能了解到如何将理论知识应用于实际项目...

    java学习笔记1

    Java学习笔记1 Java学习笔记1是学习Java过程中的笔记,主要记录了Eclipse开发环境中的快捷键使用、编辑功能、查找和调试等知识点。 Eclipse快捷键 Eclipse中有许多快捷键,掌握这些快捷键可以大大提高开发效率。...

    java下载网络图片

    在Java编程中,下载网络图片是一项常见的任务,尤其在数据抓取、网页爬虫或构建图形界面应用时。本教程将深入讲解如何使用Java...在实际开发中,还可以考虑添加异常处理、进度条显示、断点续传等功能,提升用户体验。

    论文研究-异构数据库迁移的设计和实现.pdf

    实现断点续传需要记录迁移过程中的各种状态信息,例如已经迁移完成的数据量和位置,以便在继续迁移时能够准确找到续传的位置。 文章中提到的B/S模式指的是基于浏览器和服务器的网络架构模式,它允许用户通过网页...

    java基础语法选择题

    - **b) 设置断点**: 断点是在代码的某一行设置一个标记,当程序执行到这一行时会暂停执行,以便开发者可以检查当前状态或逐步执行程序。这是调试的重要组成部分。 - **c) 单步运行**: 单步执行允许开发者逐行执行...

    JAVA上百实例源码以及开源项目源代码

    Java局域网通信——飞鸽传书源代码 28个目标文件 内容索引:JAVA源码,媒体网络,飞鸽传书 Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java...

    基于Java的网盘系统的设计与实现.pdf

    本文主要介绍了如何利用Java技术栈构建一个基于B/S架构的网盘系统,旨在提供一个方便用户管理、存储个人文件以及分享文件的平台。主要涉及的技术包括WebUploader、SpringBoot和FastDFS。 1. **需求分析** - **...

    课程设计-基于Java web ssh框架的QQ号管理系统(源码+数据库).zip

    腾讯QQ支持在线聊天、视频电话、点对点断点续传文件、共享文件、网络硬盘、自定义面板、QQ邮箱等多种功能,并可与移动通讯终端等多种通讯方式相连。1999年2月,腾讯正式推出第一个即时通信软件——“腾讯QQ”,QQ...

    java开发快捷键文档

    2. **Ctrl + Shift + B**:启用/禁用断点。 ### 源代码 1. **Ctrl + Shift + U**:切换大小写。 2. **Alt + Shift + S**:源代码菜单,包含抽取方法、内联方法等重构操作。 ### 运行 1. **Ctrl + F11**:运行...

    Eclipse 快捷键 很适合打印啊 Java

    12. **调试**:F5、F6、F7分别用于单步进入、单步跳过和单步返回,F8继续执行,Ctrl+Shift+B添加/移除断点,Ctrl+D显示调试视图,Ctrl+F11运行上次启动,Ctrl+R运行到行,Ctrl+U执行。 13. **重构**:Alt+Shift+Z...

    基于Android平台的无线医疗设备手机端软件Android远程医疗系统毕业论文.doc

    在系统中心处理部分,提到了数据采集和存储服务器模块,以及大文件断点续传的功能。此外,还讨论了系统管理软件的设计,如采用Java Web应用、B/S架构、MVC模型,并利用Tomcat服务器进行部署。 在系统调试阶段,论文...

    Java常用快捷键。绝对常用。个人总结。

    1. **设置/取消断点**:`F8`,在当前行设置或取消断点。 2. **启动调试**:`F11`,开始调试模式运行程序。 3. **单步执行**:`F6`(进入)、`F7`(跳出)、`F8`(下一步)。 4. **强制返回**:`Shift + F6`,强制...

    计算机毕业论文选题.docx

    - 这些系统通常基于B/S结构,采用Java、JSP等技术开发。 - 关键点包括用户认证、事务处理、数据安全及用户体验设计。 以上是部分选题中涉及的关键知识点,实际开发中还需要结合具体需求和技术趋势进行深入研究和...

    传智播客java_web视频教程笔记全套

    - `String s = "a" + "b" + "c" + "d"`创建了几个对象? - `String s1 = "a"; String s2 = "b"; String s3 = s1 + s2;`结果是什么? 综上所述,传智播客的java_web视频教程不仅覆盖了Eclipse的基础使用技巧,还...

Global site tag (gtag.js) - Google Analytics