📄 filedown.java
字号:
/* FileDown.java */
import javax.swing.*;
import java.io.*;
import java.net.*;
import java.util.*;
public class FileDown extends Thread
{
//定义私有成员对象
private String urlString=null; //网络路径名称字符串
private String fileString=null; //保存文件名称字符串
private int priorityInt=0; //下载线程及其子线程的优先权
private int threadnumInt=0; //下载子线程数
private long fileLong=0; //下载文件长度
private long[] startposLong; //下载子线程开始位置数组
private long[] endposLong; //下载子线程结束位置数组
private FileSplitDown[] filesplit=null; //下载子线程对象数组
private boolean stopBoolean = false;//下载停止标志
private File tempFile=null; //保存文件下载过程信息的临时文件
//构造函数
public FileDown(Vector info) throws IOException
{
urlString=info.elementAt(1).toString();
fileString=info.elementAt(2).toString();
priorityInt=Integer.parseInt(info.elementAt(4).toString());
threadnumInt=Integer.parseInt(info.elementAt(5).toString());
setPriority(priorityInt);
tempFile = new File(fileString+".dat");
if(tempFile.exists()) read_pos(); //从临时文件中读取下载位置
else //是第一次下载,从网络路径取得文件的总长度,并分配给各个子线程
{
startposLong = new long[threadnumInt];
endposLong = new long[threadnumInt];
fileLong = getFileSize();
if(fileLong == -1)
{
System.err.println("File Length is not known!");
JOptionPane.showMessageDialog(null,"未知的文件长度,发生错误,"+
"下载线程将停止.","错误...",JOptionPane.ERROR_MESSAGE);
stopBoolean=true;
}
else if(fileLong == -2)
{
System.err.println("File is not access!");
JOptionPane.showMessageDialog(null,"文件无法访问,发生错误,"+
"下载线程将停止.","错误...",JOptionPane.ERROR_MESSAGE);
stopBoolean=true;
}
else
{
for(int i=0;i<threadnumInt;i++)
startposLong[i] = (long)(i*(fileLong/threadnumInt));
for(int i=0;i<threadnumInt-1;i++)
endposLong[i] = startposLong[i+1];
endposLong[threadnumInt-1] = fileLong;
}
}
if(fileLong>0)
{
filesplit = new FileSplitDown[threadnumInt];
for(int i=0;i<threadnumInt;i++)
{
filesplit[i] = new FileSplitDown(urlString,fileString,
startposLong[i],endposLong[i],i,priorityInt);
System.out.println("Thread " + i + " , startpos = " +
startposLong[i] + ", endpos = " + endposLong[i]);
filesplit[i].start();
}
}
}//结束构造函数FileDown()
//下载文件线程的主体
public void run()
{
try
{ //等待子线程结束
boolean breakBoolean = false; //是否结束while循环
while ((!stopBoolean) && (!breakBoolean))
{
write_pos();
Thread.sleep(500);
breakBoolean = true;
for(int i=0;i<threadnumInt;i++)
if(!filesplit[i].getSplitDown())
//寻找未结束的子线程,如果有一个子线程未结束,则下载线程就不能结束
{ breakBoolean = false; break; }
else if((filesplit[i].getStart()-startposLong[i])<250)
//如果某一个子线程的下载流量过小(低于500byte/sec),则自动断开结束
//该子线程,并重新建立一个子线程
{
filesplit[i].splitDownStop();
filesplit[i]=null;
filesplit[i]=new FileSplitDown(urlString,fileString,
startposLong[i],endposLong[i],i,priorityInt);
filesplit[i].start();
}
}
if(breakBoolean)
{
tempFile.delete();
System.out.println("文件下载结束!");
}
}
catch(Exception e){e.printStackTrace (); }
}//结束函数run()
/*以下部分是公共成员函数*/
//停止文件下载
public void downStop()
{
stopBoolean = true;
for(int i=0;i<threadnumInt;i++)
filesplit[i].splitDownStop();
}
//取得文件下载的进度(0--100)
public int getProgress()
{
long total=0;
try
{
for( int i=0;i<threadnumInt;i++)//计算还未下载的字节数
total=total+filesplit[i].getEnd()-filesplit[i].getStart();
}
catch (NullPointerException e){ return 0;}
return (int)(100-(((double)total)/((double)fileLong))*100);
}
//取得文件下载线程当前的状态
public String getStatus()
{
if(stopBoolean) return "停止";
else return "运行";
}
//取得下载文件的总长度
public long getFileLength()
{
return fileLong;
}
//取得下载文件的网络路径
public String getURL()
{
return urlString;
}
/*以下部分是私有成员函数*/
//获得文件长度
private long getFileSize()
{
long lengthLong = -1;
try
{
URL url = new URL(urlString);
HttpURLConnection httpConnection;
httpConnection = (HttpURLConnection)url.openConnection ();
httpConnection.setRequestProperty("User-Agent","DDXC");
int responseInt=httpConnection.getResponseCode();
if(responseInt>=400)
{
processErrorCode(responseInt);
return -2; //-2 表示对文件操作没有权限
}
String headerString;
for(int i=1;;i++)
{
headerString=httpConnection.getHeaderFieldKey(i);
if(headerString==null) break;
if(headerString.equals("Content-Length"))
{
lengthLong = Long.parseLong(httpConnection.getHeaderField
(headerString));
break;
}
}
}
catch(IOException e){ e.printStackTrace (); }
catch(Exception e) { e.printStackTrace (); }
return lengthLong;
}//结束私有成员函数getFileSize()
//保存下载信息(文件指针位置)
private void write_pos()
{
try
{
DataOutputStream output;
output = new DataOutputStream(new FileOutputStream(tempFile));
output.writeInt(threadnumInt);
for(int i=0;i<threadnumInt;i++)
{
output.writeLong((startposLong[i]=filesplit[i].getStart()));
output.writeLong((endposLong[i]=filesplit[i].getEnd()));
}
output.writeLong(fileLong);
output.close();
}
catch(IOException e){ e.printStackTrace (); }
catch(Exception e) { e.printStackTrace (); }
}//结束私有成员函数write_pos()
//读取保存的下载信息(文件指针位置)
private void read_pos()
{
try
{
DataInputStream input;
input = new DataInputStream(new FileInputStream(tempFile));
threadnumInt = input.readInt();
startposLong = new long[threadnumInt];
endposLong = new long[threadnumInt];
for(int i=0;i<threadnumInt;i++)
{
startposLong[i] = input.readLong();
endposLong[i] = input.readLong();
}
fileLong=input.readLong();
input.close();
}
catch(IOException e) { e.printStackTrace (); }
catch(Exception e) { e.printStackTrace (); }
}//结束私有成员函数read_pos()
//显示错误代码
private void processErrorCode(int nErrorCode)
{
System.err.println("Error Code : " + nErrorCode);
}
}//结束类FileDown
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -