62,621
社区成员
发帖
与我相关
我的任务
分享 class DownLoadFile extends Thread
{
private JPanel progressPane;
private String URL;//url地址
private String saveURL;//保存地址
int nthread;//线程数
String info = new String();//字符串info
JTextArea textArea = new JTextArea();//文本区对象
JProgressBar jProgressBar;//进度条
long[] startPos;//开始字节数
long[] endPos;//结束字节数
long fileLength;//文件长度
DownLoadFileThread[] downFileSplitter;//文件下载线程数组
Timer timer;
//构造方法
public DownLoadFile(String URL, String saveURL, JTextArea textArea,
int nthread, JProgressBar jProgressBar)
{
this.jProgressBar = jProgressBar;
this.URL = URL;
this.saveURL = saveURL;
this.nthread = nthread;
this.startPos = new long[nthread];
this.endPos = new long[nthread];
this.textArea = textArea;
}
//重写run方法
public void run()
{
info = "目标文件: " + URL;
textArea.append("\n" + info);//输出目标文件地址
info = "\n 线程总数: " + nthread;
textArea.append("\n" + info);//输出线程总数
try
{
fileLength = getFileSize(URL);//获得文件长度大小
if (fileLength == -1)
{//如果无法得到文件长度,输出提示
textArea.append("\n 不可知的文件长度!请重试!!");
} else
{
if (fileLength == -2)
{//如果无法获取文件,输出提示,检查路径
textArea.append("\n 文件无法获取!请重试或检查路径!!");
} else
{//根据文件长度,确定每个线程的开始字节数和结束字节数,输出线程和下载范围
for(int i = 0; i < startPos.length; i++)
startPos[i] = (long) (i * (fileLength / startPos.length));
for (int i = 0; i < endPos.length - 1; i++)
endPos[i] = startPos[i + 1];
endPos[endPos.length - 1] = fileLength;
for (int i = 0; i < startPos.length; i++)
{
info = "线程:" + i + "下载范围:" + startPos[i] + "--"+ endPos[i];
textArea.append("\n" + info);
}
//创建文件下载线程数组对象,设置进度条
downFileSplitter = new DownLoadFileThread[startPos.length];
jProgressBar.setMaximum(100);
jProgressBar.setMinimum(0);
jProgressBar.setStringPainted(true);
jProgressBar.setString("0%");
for (int i = 0; i < startPos.length; i++)
{//创建文件下载线程对象,启动线程并输出信息
downFileSplitter[i] = new DownLoadFileThread(URL,startPos[i], endPos[i], i, textArea,jProgressBar, saveURL);
info = "线程 " + i + "启动";
textArea.append("\n" + info);
downFileSplitter[i].start();
}
//进度条设置,重写actionPerformed方法,进度条随下载进度变化
timer = new Timer(100, new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
int readTotal = 0;
boolean finished = true;
for (int i = 0; i < startPos.length; i++)
{
if (downFileSplitter[i].isAlive())
finished = false;
readTotal += downFileSplitter[i].getReadPos();
}
jProgressBar.setValue((int) ((long) (readTotal) * 100f / fileLength));
jProgressBar.setString((int) ((long) (readTotal) * 100f / fileLength)+ "%");
if (finished)
{
if ((long) readTotal == fileLength)
JOptionPane.showMessageDialog(null,"下载完成!!!");
else
JOptionPane.showMessageDialog(null,"未能完成下载!!!");
timer.stop();
}
}
});
timer.start();
}
}
} catch (Exception e)
{
e.printStackTrace();
}
}
//获取文件大小的方法,返回文件长度
public long getFileSize(String URL)
{
int fileLength = -1;
try
{//连接网络,获取响应
URL url = new URL(URL);
HttpURLConnection httpConnection = (HttpURLConnection) (url.openConnection());
int responseCode = httpConnection.getResponseCode();
if (responseCode >= 400)
{
System.out.println("Web服务器响应错误");
return -2;// Web服务器响应错误
}
String sHeader;//文件长度的文件头
for (int i = 1;; i++)// 查找标识文件长度的文件头,获取文件长度
{
sHeader = httpConnection.getHeaderFieldKey(i);
if (sHeader != null)
{
if (sHeader.equals("Content-Length"))
{//显示文件的长度
int length=httpConnection.getContentLength();
textArea.append("\n 文件长度:---"+length);
fileLength = Integer.parseInt(httpConnection.getHeaderField(sHeader));
textArea.append("\n 可知的文件长度:"+fileLength);
break;
}
} else
{
break;
}
}
} catch(Exception e)
{
e.printStackTrace();
}
return fileLength;
}
}
//定义DownLoadFileThread类,继承Thread类
class DownLoadFileThread extends Thread
{
private JProgressBar jProgressBar;//进度条
String URL;//url地址
long startPos;//开始字节数
long endPos;//结束字节数
int threadID;//线程号
JTextArea textArea=new JTextArea();//文本区
RandomAccessFile file;//随机访问文件流
private int readPos = 0;
private int in = 0;
//构造方法
public DownLoadFileThread(String URL,long startPos,long endPos,int id,JTextArea textArea
,JProgressBar jProgressBar,String saveURL)throws IOException
{
this.jProgressBar = jProgressBar;
this.URL = URL;
this.startPos = startPos;
this.endPos = endPos;
this.threadID = id;
this.textArea = textArea;
file=new RandomAccessFile(saveURL,"rw");//创建名为saveURL,权限为读写的文件
file.seek(startPos);//从startPos字节数的下一位置进行读写操作
}
//重写run方法
public void run()
{
try
{//连接地址,创建连接
URL url = new URL(URL);
HttpURLConnection httpConnection=(HttpURLConnection)url.openConnection();
String sProperty="bytes="+startPos+"-";
httpConnection.setRequestProperty("RANGE",sProperty);//设置请求属性
textArea.append("\n 线程"+threadID+"下载文件……请等待");
InputStream input=httpConnection.getInputStream();//得到输入流
byte[] buf=new byte[10000000];
int offset;
offset=(int)endPos-(int)startPos;//每个线程读取的字节数
if(offset>10000000)
offset=10000000;
while((in = input.read(buf,0,offset))>0 && startPos<endPos)
{//显示各个线程读取的字节数以及起始字节数和结束字节数,直到下载完成
if(((int) endPos - (int) startPos)<1024)
in = (int) endPos - (int) startPos;
readPos +=in;
textArea.append("\n 线程"+threadID+" 已读取"+readPos+"个字节, start is :"+startPos+" and end is:"+endPos+"。");
offset = (int) endPos - (int) startPos;
if (offset > 10000000)
offset = 10000000;
file.write(buf,0,in);//写入文件
startPos+=in;
}
textArea.append("\n 线程"+threadID+"下载完毕!!");
file.close();
input.close();
}catch(Exception ex)
{
ex.printStackTrace();
}
}
public int getReadPos()
{
return readPos;
}
public void setReadPos(int readPos)
{
this.readPos = readPos;
}
}
//定义代理类,继承JFrame类实现ActionListener接口
class ProxyPanel extends JFrame implements ActionListener
{
private String host = "000.000.000.000";//设置主机默认地址
private String port = "0000";//设置主机默认端口
private JLabel label1 = new JLabel("主机:");//标签提示
private JLabel label2 = new JLabel("端口:");//标签提示
private JTextField hosttext = new JTextField();//主机文本框
private JTextField porttext = new JTextField();//端口文本框
private JButton button = new JButton("确定");//确定按钮
//构造方法
public ProxyPanel(int x, int y)
{
//创建面板、设置面板布局,添加标签、文本框到面板中,设置位置、大小
JPanel panel = new JPanel();
panel.setLayout(null);
label1.setBounds(20, 20, 40, 20);
hosttext.setBounds(60, 20, 140, 20);
panel.add(label1, null);
panel.add(hosttext, null);
hosttext.setText(host);
label2.setBounds(20, 60, 40, 20);
porttext.setBounds(60, 60, 140, 20);
panel.add(label2);
panel.add(porttext);
porttext.setText(port);
button.setBounds(85, 100, 60, 20);//设置按钮位置、大小
button.addActionListener(this);//给按钮添加监听器
panel.add(button);//添加按钮到面板中
getContentPane().add(panel);//添加面板到内容窗
setSize(new Dimension(240, 160));//设置大小
setVisible(true);//设置可见性
setLocation(x, y);//设置位置
}
public String getHost()
{
return this.host;
}
public String getPort()
{
return this.port;
}
//重写actionPerformed方法,获取系统属性
public void actionPerformed(ActionEvent arg0)
{
if (arg0.getSource() == button)
{
host = hosttext.getText();
port = porttext.getText();
System.getProperties().put("proxySet", "true");
System.getProperties().put("proxyHost", host);
System.getProperties().put("proxyPort", port);
this.setVisible(false);
}
}
}