几个月前的一个多线程下载的小程序,可以供初学者学习。这里只贴部分核心代码,希望能够对大家有用。 package lightning.threads; import java.io.File; import java.io.IOException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.Vector; import javax.swing.JProgressBar; import javax.swing.JTable; import javax.swing.JTextArea; import javax.swing.table.DefaultTableModel; import lightning.window.LightningWindow; public class DownloadFile extends Thread { /** * @author WESTDREAM */ private String url; private String fileName; private int threadCount; private String savePath; private File file; private HttpURLConnection huc; private long fileLength; private long size; private long startPosition; private long endPosition; private String speed; private long temp = 0; private JTable table; private Object obj[] = new Object[5]; private Vector<DownloadFileBlock> vd = new Vector<DownloadFileBlock>(0); private JProgressBar jpb = new JProgressBar(); private static int row = 0; private JTextArea text; private LightningWindow parent; //无参构造器,主要用于内部公有方法调用 public DownloadFile() { } //传入LightningWindow的引用,url,文件名,线程数,保存路径,抛出MalformedURLException public DownloadFile(LightningWindow parent, String url, String fileName, int threadCount, String savePath) throws MalformedURLException { this.url = url; this.fileName = fileName; this.threadCount = threadCount; this.savePath = savePath; this.parent = parent; table = parent.getTable(); text = parent.getTextArea(); } public void run() { try { file = new File(savePath + "//" + fileName); text.append("/n" + "正在下载到:" + savePath + "//" + fileName); text.append("/n" + "文件源:" + url); //建立连接 text.append("/n" + "建立连接..."); URL u = new URL(url); huc = (HttpURLConnection) u.openConnection(); huc.connect(); text.append("/n" + "连接成功"); //获取要下载的文件长度 text.append("/n" + "获取文件长度..."); fileLength = huc.getContentLength(); text.append("/n" + "文件长度为:" + fileLength); obj[0] = "正在下载"; obj[1] = fileName; obj[2] = ((float)fileLength / (1024*1024)) + "MB"; obj[3] = jpb; obj[4] = "---------"; DefaultTableModel dtm = (DefaultTableModel)table.getModel(); dtm.addRow(obj); row ++; //对要下载的文件进行逻辑上的分块 size = fileLength / threadCount; startPosition = 0; endPosition = size - 1; int threads = 0; while(threads < threadCount) { //这里主要是防止分块不均匀,故将最后的只要小于2倍size的分成一块 text.append("/n" + "起始位置" + startPosition); text.append("/n" + "结束位置" + endPosition); if((fileLength - endPosition) / size < 2) { endPosition = fileLength - 1; } else { endPosition += size; } //按照前面的分块,分别启动分块文件下载线程下载文件 text.append("/n" + "创建线程..."); vd.addElement(new DownloadFileBlock(parent,url,file,startPosition,endPosition)); startPosition += size; threads ++; } for(int i = 0; i < vd.size(); i ++) { vd.elementAt(i).start(); text.append("/n" + vd.elementAt(i).getName() + "---启动"); } while(file.length() <= fileLength) { try { speed = ((((float)file.length() - temp) / 1204)) + "kb/s"; dtm.setValueAt(speed, row - 1, 4); temp = file.length(); jpb.setStringPainted(true); float progress = (100*file.length() / (float)fileLength); jpb.setValue((int)progress); jpb.setString(String.valueOf(progress)); table.repaint(); if(temp == fileLength) { text.append("/n" + "下载完成"); dtm.setValueAt("下载完成", row - 1, 0); dtm.setValueAt("---------", row - 1, 4); break; } Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } catch (IOException e) { e.printStackTrace(); } } } package lightning.threads; import java.io.DataInputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; import javax.swing.JTextArea; import lightning.window.LightningWindow; public class DownloadFileBlock extends Thread { /** * @author WESTDREAM */ private RandomAccessFile out; private DataInputStream dis; private String url; private File file; private HttpURLConnection huc; private long startPosition; private long endPosition; private JTextArea text; public DownloadFileBlock() { } public DownloadFileBlock(LightningWindow parent,String url,File file,long startPosition,long endPosition) { this.url = url; this.file = file; this.startPosition = startPosition; this.endPosition = endPosition; text = parent.getTextArea(); } public void run() { try { //连接资源,并进行文件分块 URL u = new URL(url); huc = (HttpURLConnection)u.openConnection(); String value = "bytes=" + startPosition + "-" + endPosition; huc.setRequestProperty("RANGE", value); huc.setRequestProperty("User-Agent", "Lightning"); dis = new DataInputStream(huc.getInputStream()); out = new RandomAccessFile(file,"rw"); int data; text.append("/n" + this.getName() + "---写入文件中..."); out.seek(startPosition); while((data = dis.read())!= -1) { out.write(data); } text.append("/n" + this.getName() + "---成功写入文件"); out.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }