import java.io.*;
/**
* 文件下载类
**/
public class DownloadFile {
public static void main( String[] args ) {
// 获取屏幕输入
BufferedReader r = null;
try {
r = new BufferedReader( new InputStreamReader( System.in ) );
String s = "";
System.out.println( "请输入需要下载的文件路径:" );
while ( ( s = r.readLine() ) != null ) {
// 判断文件路径是否已经输入过
if ( DownloadConfig.getInstance().dFile == null ) {
// 文件路径未输入的场合
if ( !"".equals(s) ) {
// 构造文件
File f = new File( s );
if ( f.exists() && f.isFile() ) {
DownloadConfig.getInstance().dFile = f;
System.out.println("请输入下载的线程数量:");
} else {
System.out.println("下载的文件不存在,请重新输入:");
}
} else {
System.out.println("文件路径不能为空,请重新输入:");
}
} else {
// 文件路径已经输入的场合
// 获取下载线程的数量
try {
DownloadConfig.getInstance().threadCount = Integer.parseInt(s);
DownloadConfig.getInstance().threadPercent = new double[DownloadConfig.getInstance().threadCount];
File f = new File( DownloadConfig.SAVE_PATH );
if ( !f.exists() ) {
f.mkdirs();
}
// 执行下载操作
download();
break;
} catch ( NumberFormatException e ) {
System.out.println("输入的数量不合法,请重新输入:");
}
}
}
} catch ( IOException e ) {
System.out.println("屏幕输入异常");
} finally {
if ( r != null ) {
try {
r.close();
} catch ( IOException e ) {
r = null;
}
}
}
}
public static void download() {
// 分割文件
BufferedInputStream buffIn = null;
try {
buffIn = new BufferedInputStream( new FileInputStream( DownloadConfig.getInstance().dFile ) );
// 获取下载文件的大小
int fileSize = buffIn.available();
// 获取每个线程下载的最小字节数
int cnt = fileSize / DownloadConfig.getInstance().threadCount;
// 整除标志
boolean flg = true;
if ( fileSize % DownloadConfig.getInstance().threadCount != 0 ) {
flg = false;
}
// 构造下载线程
DownloadProcess[] dps = new DownloadProcess[DownloadConfig.getInstance().threadCount];
// 启动监听器
new DownloadListener().start();
for ( int i = 0; i < dps.length; i++ ) {
if ( i != dps.length - 1 ) {
dps[i] = new DownloadProcess( i, cnt, cnt );
} else {
if ( flg ) {
dps[i] = new DownloadProcess( i, cnt, cnt );
} else {
dps[i] = new DownloadProcess( i, cnt, fileSize - (DownloadConfig.getInstance().threadCount - 1)*cnt );
}
}
dps[i].start();
}
} catch ( IOException e ) {
System.out.println("输入输出异常");
} finally {
if ( buffIn != null ) {
try {
buffIn.close();
} catch ( IOException e ) {
buffIn = null;
}
}
}
}
}
/**
*
*/
class DownloadListener extends Thread {
public void run() {
BufferedInputStream buffIn = null;
BufferedOutputStream buffOut = null;
try {
// 监听下载进度
// 下载完成的线程数量
int count = 0;
while ( count != DownloadConfig.getInstance().threadPercent.length ) {
count = 0;
System.out.println();
System.out.println("***********文件下载监视中***********");
for ( int i = 0; i < DownloadConfig.getInstance().threadPercent.length; i++ ) {
int percent = (int)(DownloadConfig.getInstance().threadPercent[i]*100);
System.out.println("第"+i+"个线程下载的进度是:" + percent + "%");
if ( percent == 100 ) {
count++;
}
}
System.out.println("************************************");
sleep( 50 );
}
// 合并文件
buffOut = new BufferedOutputStream( new FileOutputStream( DownloadConfig.SAVE_PATH + DownloadConfig.getInstance().dFile.getName(), true ) );
for ( int i = 0; i < DownloadConfig.getInstance().threadCount; i++ ) {
buffIn = new BufferedInputStream( new FileInputStream( DownloadConfig.SAVE_PATH + DownloadConfig.getInstance().dFile.getName() + i + ".bak" ) );
int b = 0;
while ( (b = buffIn.read()) != -1 ) {
buffOut.write(b);
}
buffOut.flush();
// 关闭输入流
buffIn.close();
}
// 删除临时文件
for ( int i = 0; i < DownloadConfig.getInstance().threadCount; i++ ) {
File f = new File(DownloadConfig.SAVE_PATH + DownloadConfig.getInstance().dFile.getName() + i + ".bak");
if ( f.exists() && f.isFile() ) {
f.delete();
}
}
} catch ( Exception e ) {
System.out.println("异常");
} finally {
if ( buffIn != null ) {
try {
buffIn.close();
} catch ( IOException e ) {
buffIn = null;
}
}
if ( buffOut != null ) {
try {
buffOut.close();
} catch ( IOException e ) {
buffOut = null;
}
}
}
}
}
class DownloadProcess extends Thread {
// 线程索引
private int index;
// 线程下载最小字节数
private int cnt;
// 当前线程需要下载的字节数
private int size;
public DownloadProcess( int index, int cnt, int size ) {
this.index = index;
this.cnt = cnt;
this.size = size;
}
// 线程下载
public void run() {
BufferedInputStream buffIn = null;
BufferedOutputStream buffOut = null;
try {
buffIn = new BufferedInputStream(
new FileInputStream( DownloadConfig.getInstance().dFile ) );
buffOut = new BufferedOutputStream(
new FileOutputStream(
DownloadConfig.SAVE_PATH + DownloadConfig.getInstance().dFile.getName() + index + ".bak" ) );
// 跳过相应的字节
buffIn.skip( index * cnt );
int b = 0;
int num = 0;
while ( (b = buffIn.read()) != -1 && num < size ) {
num++;
buffOut.write(b);
DownloadConfig.getInstance().threadPercent[index] = num * 1.0 / size;
}
// 当前线程下载完毕
DownloadConfig.getInstance().threadPercent[index] = 1;
buffOut.flush();
} catch ( IOException e ) {
System.out.println("输入输出异常");
} finally {
if ( buffIn != null ) {
try {
buffIn.close();
} catch ( IOException e ) {
buffIn = null;
}
}
if ( buffOut != null ) {
try {
buffOut.close();
} catch ( IOException e ) {
buffOut = null;
}
}
}
}
}
/**
* 文件下载配置类
*/
class DownloadConfig {
// 存储文件的路径
public static final String SAVE_PATH = "D:\\download";
// 下载文件
public File dFile = null;
// 下载的线程数量
public int threadCount = 0;
// 下载线程的进度数组
public double[] threadPercent = null;
/****** 单例 *******/
private static DownloadConfig config = new DownloadConfig();
private DownloadConfig() {}
public static DownloadConfig getInstance() {
return config;
}
}
分享到:
相关推荐
"Fish文库文档下载工具"的核心功能在于其对多种文档网站的兼容性,能够突破常规的在线预览限制,将文档转化为可本地存储的PDF文件。这样,用户就可以随时随地查阅,无需依赖网络连接,极大地提高了学习和工作的效率...
在提供的压缩包文件中,“ExuiKrnln_Win32.lib”可能是一个动态链接库文件,用于支持“萝卜头文档下载器.exe”的功能实现。这类库文件通常包含可被其他程序调用的函数,可能包含了解析网页、模拟登录、抓取下载链接...
总之,"基于Java的book118文档下载器"是一个综合运用了网络请求、HTML解析、文件操作等多种Java技术的实用工具,其具体实现会涉及到网络编程、数据解析、文件I/O等多个计算机科学和技术领域。对于学习Java编程和网络...
在线文档下载器可能使用此库来解析和处理从网站下载的PDF文件,确保用户可以本地存储和阅读这些文档。 “iDocDown.exe”是主程序执行文件,是在线文档下载器的核心部分。它包含了实现下载功能的算法和逻辑,能够...
6. **新建 文本文档.txt**:这可能是示例中的一个测试文件,用于演示如何通过Ajax进行下载。在实际应用中,这个文件的名称和类型将由用户选择或由业务逻辑决定。 具体实现步骤: 1. **前端**:在JSP文件中,使用...
【原创力文档下载工具】利用Python下载原创力文档是一个典型的Web爬虫应用场景,它涉及到Python编程语言、网络请求、文件处理以及可能的HTML解析技术。在这个项目中,开发者使用Python来自动化获取并下载原创力平台...
萝卜头文档下载器是一款Windows端的免费文档下载工具,可以帮助我们下载各种常用文档,降低获取成本!软件下载好后无需安装,就可以直接打开使用。 界面非常的干净整洁,支持下载的范围也非常广泛,支持范文、协议书...
这些工具能够解析百度文库的页面,抓取文档内容并将其转换成本地文件。使用这类工具时,用户需要复制百度文库文档的网页链接,然后粘贴到工具的输入框内,按照提示进行操作。值得注意的是,这种方法可能受制于网站的...
豆丁网免费下载器(冰点)无需登录也无需积分,只需要将需要下载的文档的网页地址复制在软件的录入框中就可以自由下载,并最终生成pdf文件。对部分pdf文件能够提取文字生成txt。 豆丁网免费下载器还支持自由下载百度、...
visual studio 2010的帮助文档很难下载,一方面文件很多很大,全部文档超过1GB,使用微软自带的 或者辅助工具,由于没有发挥多线程和断点续传的特点,下载速度很慢,容易失败。 另一方面迅雷等下载工具,可以实现...
国密规范文档所有标准稳当的下载链接,SM2/SM3/SM4/SM9等,各种国密产品检测规范
【描述】"文档下载器" 提供了一个集成化的解决方案,让用户能够轻松下载网络上的文档资源,特别是可能存在于各种文档分享平台上的PDF、SWF等格式的文件。它可能包含了用于处理不同文件类型的组件,以及一些支持程序...
在提供的压缩包子文件“Fish-v324-0712”中,我们可以推测这可能是冰点文档下载器的一个版本,其中可能包含了软件的执行文件、帮助文档、许可证文件等组成部分。用户在下载这个压缩包后,需要解压并按照指示安装和...
标题中的“pb实现http文件下载功能--源代码 可以直接使用”指的是使用PowerBuilder(简称PB)编程语言实现HTTP协议进行文件下载的功能,并且提供了可以直接使用的源代码。这个功能在软件开发中常用于实现自动更新...
豆丁文档下载破解器. 豆丁文档下载破解器. 豆丁文档下载破解器.
由于在学习numpy数据分析的时候没有csv类型文件,又懒得自己一个个敲字,便想来csdn里随便下载一个。然而......居然要钱啊!!!!!!!我没钱,所以自己写了个,我不要你们的钱,麻烦各位拿资源的时候吱一声,这是...
标题中的“百度或豆丁的原始文件 下载 免积分”指的是从百度文库或豆丁网这两个在线文档分享平台上获取原始文件的方式,通常这些平台为了盈利,会限制用户免费下载高质量的文档,需要消耗积分或者购买。但这个标题...
综上所述,"豆丁当当文档下载"涉及到的技术点包括文档分享平台的使用、文件下载工具、文件格式转换(如SWF到PDF)、文档管理以及特定平台的文件格式(如DOCIN)。这些工具和服务的使用可以帮助用户更有效地获取和...
为了解决这一问题,豆丁文档下载工具应运而生,旨在为用户提供无需登录即可下载豆丁网文档的途径,从而节约宝贵的时间和精力。 豆丁网提供的是一个集合了各类专业文档、研究报告和学习资料的资源宝库。无论是在学术...