标签:div index mac append 会员 can 消息 connect 新浪微博
在tomcat6.0的webapps\ROOT下放一个.exe的可运行文件(若放.mp3、.jpg等格式的文件可能下载过程出现损坏还是能够查看的,若是.exe可运行文件下载过程出现损坏就不可运行了)。然后启动tomcat,双击bin目录下的startup.bat,出现下面的界面
记得不要关闭这个窗口,若关闭了后面的文件下载会出错的。
Android的布局文件代码例如以下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<EditText
android:id="@+id/et_path"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:text="http://172.29.168.1:8088/fengxing.exe" />
<ProgressBar
android:id="@+id/pb"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="28dp" />
<Button
android:id="@+id/bt"
android:onClick="download"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="下载" />
<TextView
android:id="@+id/tv_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="眼下下载的进度:" />
</LinearLayout>
为了方便,在代码中写死了下载路径。
MainActivity中的代码例如以下:
package com.myself.download;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.text.TextUtils;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
protected static final int DOWN_LOAD_ERROR = 1;
protected static final int SERVER_ERROR = 2;
protected static final int SD_UNABLE = 3;
public static final int DOWN_LOAD_FINISH = 4;
public static final int UPDATE_TEXT = 5;
public static int threadCount = 3;
public static int runingThread =3;
public int currentProcess=0;//当前的进度
private EditText et_path;
private ProgressBar pb;
private TextView tv_show;
private Handler handler=new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case DOWN_LOAD_ERROR:
Toast.makeText(MainActivity.this, "下载错误", 1).show();
break;
case SERVER_ERROR:
Toast.makeText(MainActivity.this, "server连接错误", 1).show();
break;
case SD_UNABLE:
Toast.makeText(MainActivity.this, "SD卡不可用", 1).show();
break;
case DOWN_LOAD_FINISH:
Toast.makeText(MainActivity.this, "资源完成下载", 1).show();
break;
case UPDATE_TEXT:
tv_show.setText("眼下下载的进度:"+pb.getProgress()*100/pb.getMax()+"%");
break;
default:
break;
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_path=(EditText) findViewById(R.id.et_path);
pb=(ProgressBar) findViewById(R.id.pb);
tv_show=(TextView) findViewById(R.id.tv_show);
}
public void download(View v){
final String path=et_path.getText().toString().trim();
if(TextUtils.isEmpty(path)){
Toast.makeText(this, "下载路径不能为空", 1).show();
return ;
}
new Thread(){
public void run() {
// 1.连接server,获取要下载的文件长度。并创建一个跟要下载资源大小一样的暂时文件
try {
//String path = "http://172.29.168.1:8088/fengxing.exe";
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
int code = conn.getResponseCode();
System.out.println("code: "+code);
if (code == 200) {
// server返回的数据的长度实际上就是文件的长度
int length = conn.getContentLength();
pb.setMax(length);
//System.out.println("文件总长度:" + length);
//推断sd卡是否可用
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
//在client创建一个与要下载的资源相同大小的暂时文件
RandomAccessFile raf=new RandomAccessFile("/sdcard/fengxing.exe", "rwd");
//设置文件的大小
raf.setLength(length);
raf.close();
// 如果是3个线程去下载
// 平均每个线程下载的资源的大小
int blockSize = length / threadCount;
for (int threadId = 1; threadId <= threadCount; threadId++) {
// 第一个线程開始下载的位置
int startIndex = (threadId - 1) * blockSize;
int endIndex = (threadId * blockSize) - 1;
if (threadId == threadCount) {// 最后一个线程下载的资源就是剩下的资源
endIndex = length;
}
System.out.println("线程"+threadId+"线程下载的位置: "+startIndex+"------->"+endIndex);
new DownlLoad(threadId, startIndex, endIndex, path).start();
}
}else{
System.out.println("sd卡不可用...");
Message msg=new Message();
msg.what=SD_UNABLE;
handler.sendMessage(msg);
}
} else {
System.out.println("server连接错误...");
Message msg=new Message();
msg.what=SERVER_ERROR;
handler.sendMessage(msg);
}
} catch (Exception e) {
e.printStackTrace();
Message msg=new Message();
msg.what=DOWN_LOAD_ERROR;
handler.sendMessage(msg);
}
};
}.start();
}
/**
* 下载文件的子线程 每个线程下载相应位置的文件
* @author Administrator
*
*/
public class DownlLoad extends Thread{
private int threadId;
private int startIndex;
private int endIndex;
private String path;
/**
*
* @param threadId 线程Id
* @param startIndex 開始下载的位置
* @param endIndex 结束位置
* @param path 要下载的资源所在路径
*/
public DownlLoad(int threadId, int startIndex, int endIndex, String path) {
this.threadId = threadId;
this.startIndex = startIndex;
this.endIndex = endIndex;
this.path = path;
}
@Override
public void run() {
try {
//检查是否存在记录了已经下载长度的文件。若存在则读取文件的内容
File tempFile=new File("/sdcard/"+threadId+".txt");
if(tempFile.exists()&&tempFile.length()>0){
FileInputStream fis=new FileInputStream(tempFile);
byte[] temp=new byte[1024];
int leng=fis.read(temp);
String downloadLen=new String(temp,0,leng);
int downloadInt=Integer.parseInt(downloadLen);
int alreadyDownInt=downloadInt-startIndex;//已经下载的进度
currentProcess+=alreadyDownInt;//若已经有下载的,又一次设置进度
startIndex=downloadInt;//改动下载真实的開始位置
}
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
//重要:请求server下载部分的文件 指定下载的资源范围
conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);
System.out.println("线程"+threadId+"线程又一次開始下载的位置: "+startIndex+"------->"+endIndex);
int code = conn.getResponseCode();//200代表的是全部的资源 206代表的是部分资源
//System.out.println("code:"+code);
if(code==206){
InputStream is=conn.getInputStream();//已经设置了请求的位置 返回当前位置相应的文件的输入流
RandomAccessFile raf=new RandomAccessFile("/sdcard/fengxing.exe", "rwd");
raf.seek(startIndex);//定位開始位置
int len=0;
byte[] buff=new byte[1024];
int total=0;//记录已经下载的文件的长度
while((len=is.read(buff))!=-1){
//FileOutputStream fos=new FileOutputStream(file);
RandomAccessFile file=new RandomAccessFile("/sdcard/"+threadId+".txt","rwd");//记录当前线程下载的长度
raf.write(buff, 0, len);
total+=len;
//System.out.println("线程"+threadId+" 下载长度:"+total);
file.write((""+(total+startIndex)).getBytes());
file.close();
//更新进度条
synchronized (MainActivity.this) {
currentProcess+=len;//获取全部线程下载的总进度
pb.setProgress(currentProcess);//更改进度条的进度
Message msg=Message.obtain();//复用旧的消息
msg.what=UPDATE_TEXT;
handler.sendMessage(msg);
}
}
is.close();
raf.close();
System.out.println("线程"+threadId+"完成下载...");
}else{
System.out.println("线程"+threadId+"下载失败...");
}
/*File deleteFile=new File(threadId+".txt");
deleteFile.delete();*/
} catch (Exception e) {
e.printStackTrace();
} finally{
threadFinish();
}
}
private synchronized void threadFinish() {
//这部分的作用:防止某一个记录文件在资源下载完后没有被删除
runingThread--;
if(runingThread==0){
for(int i=1;i<=3;i++){
File file=new File("/sdcard/"+i+".txt");
file.delete();
}
System.out.println("资源已经完成下载。删除全部的下载记录...");
Message msg=new Message();
msg.what=DOWN_LOAD_FINISH;
handler.sendMessage(msg);
}
}
}
}
在下载的过程中,退出程序,然后在打开程序,程序会接着在原来的基础上继续下载。
最后打开File Explor中的sdcard,就会发现下载的文件:
源码的下载地址:http://download.csdn.net/detail/dangnianmingyue_gg/9026189
举报

直接使用单线程下载HTTP文件对我们来说是一件很easy...


0条评论