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;
}
}
分享到:
相关推荐
豆丁网免费下载器(冰点)无需登录也无需积分,只需要将需要下载的文档的网页地址复制在软件的录入框中就可以自由下载,并最终生成pdf文件。对部分pdf文件能够提取文字生成txt。 豆丁网免费下载器还支持自由下载百度、...
用ajax实现的java文件打包下载。可以输入扩展名选择文件下载。
在线下载的方法(付费一2般不可能全部下载!
由于在学习numpy数据分析的时候没有csv类型文件,又懒得自己一个个敲字,便想来csdn里随便下载一个。然而......居然要钱啊!!!!!!!我没钱,所以自己写了个,我不要你们的钱,麻烦各位拿资源的时候吱一声,这是...
visual studio 2010的帮助文档很难下载,一方面文件很多很大,全部文档超过1GB,使用微软自带的 或者辅助工具,由于没有发挥多线程和断点续传的特点,下载速度很慢,容易失败。 另一方面迅雷等下载工具,可以实现...
ASP.NET中提供可以在页面下载存储在后台的文件,很好用哦
用Visuall C++实现远程文件下载,这只是word文档。。。
将豆丁文档转化为pdf 免除豆丁收费要求
utf-8文档下载,有需要的可以下载一下,
豆丁网文件一般只能看,不能下,本工具可把豆丁网文件下载到本地,并保存成pdf文件
库函数stdio.h文件下载~………………
1、在本站下载解压,得到小叶文库下载器软件包; 2、首先前往文库网站找到需要下载的文库 3、将其文库地址复制粘贴到软件中,进行解析下载;...4、之后下载好的文件可在本自录下的Download文件夹进行查看。
redis.conf Redis配置文件 下载 redis.conf 配置详解 Redis配置文件redis.conf 详解1.基本配置内存单位的表示# 1k => 1000 bytes# ...Redis 的详细介绍Redis 的下载地址
Java实现文件下载功能,以WORD文档方式展现给用户看。
豆丁网文档下载器 第一次运行请先运行bat文件,当文件处理时请保证您的当前磁盘有足够的空间
python
Visual Studio 2012 官方离线文档 下载地址
sharepoint 2010 实现文档下载次数
文件下载的jsf程序...................(用poi导出excel文档)
[download id="1,2,3" category="4,5,6"] 为显示多个下载文件为1,2,3的文档,category=”4,5,6″为对应的分类ID。 b.在页面中添加下载:当你添加页面时在内容框插入:[page_download]或[page_download category=...