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;
}
}
文件下载
最新推荐文章于 2022-11-23 19:23:01 发布