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”的功能实现。这类库文件通常包含可被其他程序调用的函数,可能包含了解析网页、模拟登录、抓取下载链接...
标题中的“doc,ppt等范文文档下载器”指的是一个工具,它可以帮助用户获取doc和ppt这类格式的文档,特别是那些通常需要付费或消耗积分才能在特定网站上下载的文件。这种下载器通常通过抓取网页数据或者利用API接口...
总之,"基于Java的book118文档下载器"是一个综合运用了网络请求、HTML解析、文件操作等多种Java技术的实用工具,其具体实现会涉及到网络编程、数据解析、文件I/O等多个计算机科学和技术领域。对于学习Java编程和网络...
在线文档下载器可能使用此库来解析和处理从网站下载的PDF文件,确保用户可以本地存储和阅读这些文档。 “iDocDown.exe”是主程序执行文件,是在线文档下载器的核心部分。它包含了实现下载功能的算法和逻辑,能够...
6. **新建 文本文档.txt**:这可能是示例中的一个测试文件,用于演示如何通过Ajax进行下载。在实际应用中,这个文件的名称和类型将由用户选择或由业务逻辑决定。 具体实现步骤: 1. **前端**:在JSP文件中,使用...
【原创力文档下载工具】利用Python下载原创力文档是一个典型的Web爬虫应用场景,它涉及到Python编程语言、网络请求、文件处理以及可能的HTML解析技术。在这个项目中,开发者使用Python来自动化获取并下载原创力平台...
萝卜头文档下载器是一款Windows端的免费文档下载工具,可以帮助我们下载各种常用文档,降低获取成本!软件下载好后无需安装,就可以直接打开使用。 界面非常的干净整洁,支持下载的范围也非常广泛,支持范文、协议书...
标题中的“超级好用的百度文档下载工具”指的是一个专门设计用于从百度文库下载文档的应用程序。这个工具旨在提供一种高效、简便的方式来获取百度文库中的资源,从而避免在线阅读时可能出现的不便,比如广告干扰、...
豆丁网免费下载器(冰点)无需登录也无需积分,只需要将需要下载的文档的网页地址复制在软件的录入框中就可以自由下载,并最终生成pdf文件。对部分pdf文件能够提取文字生成txt。 豆丁网免费下载器还支持自由下载百度、...
1、在本站下载解压,得到小叶文库下载器软件包; 2、首先前往文库网站找到需要下载的文库 3、将其文库地址复制粘贴到软件中,进行解析下载;...4、之后下载好的文件可在本自录下的Download文件夹进行查看。
对于"Fish-v321"这个文件,根据上下文推测,这可能是某个特定的在线文档下载神器的版本号或者是该工具的安装包文件名。具体的功能和使用方法,可能需要进一步查阅相关软件的说明书或者进行实际操作来了解。总的来说...
需要注意的是,虽然冰点文档下载器可以免费下载这些文档,但下载的文件质量可能与原版有所差异,例如可能存在格式转换后的问题,如图片模糊或排版错乱。因此,在实际使用时,用户需要根据下载后的文件质量来调整自己...
visual studio 2010的帮助文档很难下载,一方面文件很多很大,全部文档超过1GB,使用微软自带的 或者辅助工具,由于没有发挥多线程和断点续传的特点,下载速度很慢,容易失败。 另一方面迅雷等下载工具,可以实现...
至于文件`idocdown_v28`,这可能是该文档下载工具的版本号或者是程序的执行文件名。在实际使用中,用户需要将这个文件解压并安装在本地计算机上,然后按照软件的指示操作,输入目标文档的网址,工具便会自动开始下载...
国密规范文档所有标准稳当的下载链接,SM2/SM3/SM4/SM9等,各种国密产品检测规范
【描述】"文档下载器" 提供了一个集成化的解决方案,让用户能够轻松下载网络上的文档资源,特别是可能存在于各种文档分享平台上的PDF、SWF等格式的文件。它可能包含了用于处理不同文件类型的组件,以及一些支持程序...
在提供的压缩包子文件“Fish-v324-0712”中,我们可以推测这可能是冰点文档下载器的一个版本,其中可能包含了软件的执行文件、帮助文档、许可证文件等组成部分。用户在下载这个压缩包后,需要解压并按照指示安装和...
标题中的“pb实现http文件下载功能--源代码 可以直接使用”指的是使用PowerBuilder(简称PB)编程语言实现HTTP协议进行文件下载的功能,并且提供了可以直接使用的源代码。这个功能在软件开发中常用于实现自动更新...