⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 download.java

📁 多线程简单下载器 j2se实现 多线程简单下载器 j2se实现
💻 JAVA
字号:
package cn.dg.nitpro.globle;

import java.io.*;
import java.net.*;
import java.text.DecimalFormat;
import java.util.*;
import javax.swing.JProgressBar;

public class DownLoad implements Runnable, Serializable{
	
	private final static int SIZE = 1024 * 10;
	private int threadcount = 5;
	
	private transient boolean started = false;
	private transient ThreadGroup group;
	
	private URL url;
	private File SaveFile;
	private int FileLength;
	private int readLength = 0;
	
	private Vector<Integer> NotReadBlock;
	private Vector<Integer> ReadingBlock = new Vector<Integer>();
	private transient MonitorThread monitor;
	
	private void updateStatus(){
		if (started){
			gui.status.setText("下载中");
		}else if (readLength == FileLength){
			gui.status.setText("已完成");
		}else{
			gui.status.setText("暂停");
		}
	}
	private void updatePercent(){
		gui.percent.setText((int)(readLength / (double)FileLength * 100) + "%");
	}
	
	private TaskPanel gui;
	public void BindPanel(TaskPanel gui){
		this.gui = gui;
		
		gui.taskname.setText(Utils.getFileName(url));
		
		gui.progress.setMinimum(0);
		gui.progress.setMaximum(FileLength);
		gui.progress.setValue(readLength);
		
		updatePercent();
		updateStatus();
		
		//gui.rate.setText("0k/s");
		gui.threadcount.setText(String.valueOf(threadcount));
		
		gui.bind(this);
	}
	
	public DownLoad(String downloadurl, String SavePath, String SaveFileName){
		URLConnection cn = null;
		
		try{
			url = new URL(downloadurl);
			cn = url.openConnection();
			cn.connect();
		}catch(Exception e){
			AppendToLog("URL " + downloadurl + " 连接失败! " );
			
			return;
		}
		
		try{
			if (cn instanceof HttpURLConnection){
				if (((HttpURLConnection)cn).getResponseCode() != 200){
					AppendToLog("URL '" + downloadurl + "' 连接失败! " );
					
					return;
				}
			}
		}catch(Exception e){
		}
		
		if (!Utils.CreateDir(SavePath)){
			AppendToLog("'" + SavePath + "' 不是合法的目录! " );
			
			return;
		}
		
		if (SaveFileName == null || SaveFileName.trim().length() == 0){
			SaveFileName = Utils.getFileName(url);
		}
		
		FileLength = cn.getContentLength();
		SaveFile = new File(SavePath, SaveFileName);
		
		int blockcount = FileLength / SIZE + (FileLength % SIZE == 0?0:1);
		
		NotReadBlock = new Vector<Integer>();
		for (int i=0;i<blockcount ;i++ )
		{
			NotReadBlock.add(i);
		}
		
		group = new ThreadGroup(url.getFile());
	}
	
	public void reset(){
		if (group == null){
			group = new ThreadGroup(url.getFile());
		}
		
		if (!ReadingBlock.isEmpty()){
			NotReadBlock.addAll(ReadingBlock);
			ReadingBlock.clear();
		}
	}
	
	public void start(){
		if (group == null){
			return;
		}
		
		if (!started)
		{
			started = true;
			updateStatus();
			for (int i=0;i<threadcount ;i++ )
			{
				new Thread(group, this).start();
			}
			
			monitor = new MonitorThread();
			monitor.setDaemon(true);
			monitor.start();
		}
	}
	
	public void stop(){
		if (started){
			try{
				started = false;
				updateStatus();
				group.stop();
				monitor.stop();
				
				reset();
			}catch(Exception e){
			}
		}
	}
 
	private Thread previousthread;
	private boolean IsThreadStop(){
		synchronized (group){
			while (previousthread != null && previousthread.getState() != Thread.State.TERMINATED){
				Thread.yield();
			}
			
			if (group.activeCount() > threadcount){
				return true;	
			}
			
			previousthread = null;
			return false;
		}
	} 
	
	public synchronized int GetNoReadBlock(){
		if (NotReadBlock.isEmpty())
		{
			return -1;
		}
		
		int pos = NotReadBlock.remove(0);
		ReadingBlock.add(pos);

		return pos;
	}

	public synchronized void ReadSucc(int pos){
		ReadingBlock.removeElement(pos);
	}
	
	public synchronized void ReadFail(int pos){
		ReadingBlock.removeElement(pos);
		NotReadBlock.add(pos);
	}

	public void run(){
		int blockpos = -1;
		RandomAccessFile f = null;
		BufferedInputStream in = null;
		try{
			f = new RandomAccessFile(SaveFile, "rw");

			URLConnection cn = url.openConnection();
			cn.connect();
			
			in = new BufferedInputStream(cn.getInputStream());
			
			byte[] buf = new byte[SIZE];
			int len, startpos, skiplen;
			int previousPos = 0;
			long skiped;
			
			while(started && !IsThreadStop() && (blockpos = GetNoReadBlock()) != -1)
			{
				if (blockpos < previousPos){
					ReadFail(blockpos);
					
					if (!NotReadBlock.isEmpty())
						new Thread(group, this).start();
					
					break;
				}
				
				skiplen = (blockpos - previousPos) * SIZE;
				while ((skiped = in.skip(skiplen)) < skiplen){
					skiplen -= skiped;
				}
				
				len = startpos = 0;
				while ((startpos = in.read(buf, len, SIZE - len)) > 0){
					len += startpos;
				}
				
				if (len > 0)
				{
					f.seek(blockpos * SIZE);
					f.write(buf, 0, len);

					ReadSucc(blockpos);
					
					previousPos = blockpos + 1;
					readLength += len;
					gui.progress.setValue(gui.progress.getValue() + len);
					updatePercent();
				}
			}
			in.close();
			f.close();
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			try{
				if (f != null)
					f.close();
				if (in != null){
					in.close();
				}
			}catch(Exception e){}
		}
		
		if (readLength == FileLength){
			started = false;
			updateStatus();
		}
	}

	void AppendToLog(String msg){
		System.out.println(msg);
	}
	
	class MonitorThread extends Thread{
		DecimalFormat format = new DecimalFormat("####.#");
		
		public void run(){
			int beforeread , afterread;
			long before, timespan;
			double rate;
			
			while (started){
				//System.out.println("Thread Count: " + group.activeCount() + "  " + Thread.currentThread().getName());
				beforeread = readLength;
				before = System.currentTimeMillis();
				
				try{
					sleep(1000);
				}catch(Exception e){}
				
				afterread = readLength;
				timespan = System.currentTimeMillis() - before;
				
				rate = (double)(afterread - beforeread) / timespan * 1000;
				if (started)
					gui.rate.setText(format(rate));
			}
		}
		
		private String format(double num){
			String unit;
			if (num >= 1024 * 1024){
				num = num / 1024 / 1024;
				unit = " m/s";
			}else if (num >= 1024 || num == 0){
				num = num / 1024;
				unit = " k/s";
			}else{
				unit = " bps/s";
			}
			
			//return ((int)(num * 10)) / 10.0 + unit;
			return format.format(num) + unit; 
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -