异步任务下载(断点续传)

/** 用来存放每一个正在进行的下载任务 */

public static List<Map<String, DownFileTask>> listTask = new ArrayList<Map<String, DownFileTask>>();



.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface arg0, int arg1) {
fileMap=((MyApplication)getApplication()).getFileMap();


DownFileTask downFileTask=new DownFileTask(ContentActivity.this,getSDPath(),fileName,fileMap);

Map<String, DownFileTask> map = new Hashtable<String, DownFileTask>();
map.put(fileName, downFileTask);
listTask.add(map);




downFileTask.execute(Path);





package com.mw.guahu.activity.my.download;


import java.util.ArrayList;
import java.util.List;


import com.mw.guahu.R;
import com.mw.guahu.activity.ContentActivity;






import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.mw.guahu.activity.my.download.DownFileTask;


public class FileAdapter extends BaseAdapter {


private Context mContext;
// private ArrayList<HashMap<String, String>> aList = null;
private List<DownloadFile> list = null;
private LayoutInflater mInflater;
private ViewHolder holder;

public FileAdapter(Context context, List<DownloadFile> list) {
this.mInflater = LayoutInflater.from(context);
this.mContext = context;
this.list = list;
}

@Override
public int getCount() {
return list.size();
}


@Override
public Object getItem(int position) {
return list.get(position);
}


@Override
public long getItemId(int position) {
return list.get(position).getId();
}


@Override
public View getView(final int position, View convertView, ViewGroup parent) {


if (convertView == null) {
convertView = mInflater.inflate(R.layout.downloadmanager_item, null);
holder = new ViewHolder();
holder.titleTextView=(TextView) convertView.findViewById(R.id.titleTextView);
holder.pause_load=(TextView) convertView.findViewById(R.id.pause_load);
holder.progressBar1=(ProgressBar) convertView.findViewById(R.id.progressBar1);
holder.dloaded=(TextView) convertView.findViewById(R.id.dames);
convertView.setTag(holder);


}else{
holder = (ViewHolder) convertView.getTag();
}

holder.titleTextView.setText(list.get(position).getFileName());
holder.progressBar1.setProgress((int) (list.get(position).getDownloadSize()*1.0/list.get(position).getFileSize()* 100));




holder.dloaded.setText(String.format("%.2fMB", list.get(position).getDownloadSize()/1024f/1024)+"/"+
String.format("%.2fMB", list.get(position).getFileSize()/1024f/1024)+"("+list.get(position).getDownloadSize()*1.0/list.get(position).getFileSize()* 100+"%"+")");


holder.pause_load.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {

for(int i=0;i<ContentActivity.listTask.size();i++){
DownFileTask pauseTask = null;
pauseTask=ContentActivity.listTask.get(i).get(list.get(position).getFileName());
if(pauseTask !=null){
if(holder.pause_load.getText().equals("下载")){
Toast.makeText(mContext, "点击暂停", 1).show();
holder.pause_load.setText("暂停");
pauseTask.pause();
}else if(holder.pause_load.getText().equals("暂停")){
Toast.makeText(mContext, "点击继续", 1).show();
holder.pause_load.setText("下载");
pauseTask.continued();
}

}else{
Toast.makeText(mContext, "没有", 1).show();
}
}

}
});
return convertView;
}




public final class ViewHolder {
public TextView titleTextView;//标题
public TextView pause_load;//下载
public ProgressBar progressBar1;//进度条
public TextView dloaded;//下载量

}


}






package com.mw.guahu.activity.my.download;




import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Map;


import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;








import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;


public class DownFileTask extends AsyncTask<String, Integer, String> {


Handler handler;  //用于下载完成之后的客户端回调
Context context;  //上下文对象
String fileName = ""; //要下载资源名称
String url="";
String path="";
int fileSize;
Message msg;
Map<String, DownloadFile> fileMap;
private boolean isFinished = false; //用于标志是否下载完成
DownloadFile downloadFile;
boolean isDown = false;
private boolean paused = false;

public DownFileTask(){

}


public DownFileTask(Context context, String path,String fileName,Map<String, DownloadFile> fileMap)
{
this.context = context;
// this.url=url;
this.path=path;
this.fileName=fileName;
this.fileMap=fileMap;
downloadFile=new DownloadFile();
}

/**
* 暂停下载
*/
public void pause()
{
isDown = true;
}

/**
* 继续下载
*/
public void continued()
{
isDown = false;
}


@Override
protected void onPreExecute() {
Log.i("==fileSize==", "调用了onPreExecute");


}


@Override
protected void onPostExecute(String result) {
Log.i("==fileSize==", "调用了onPostExecute");
if(result.equals("下载完成"))
{
Log.i("==fileSize==", "现在完成");
downloadFile.setDownloadState("完成");
fileMap.put(fileName, downloadFile);
}

}


@Override
protected void onProgressUpdate(Integer... values) {

}


@Override
protected void onCancelled() {


super.onCancelled();

}




@Override
protected String doInBackground(String... params) {
Log.i("params", params.length+"");
url=params[0];
Log.i("params", url);
Log.i("==fileSize==", "调用了doInBackground");
Message message = new Message();
if(!"".equals(url)){
// fileName = url.substring(url.lastIndexOf("/") + 1);
InputStream inputStream = null;
FileOutputStream outputStream = null;
try {

URL myuUrl = new URL(url);
URLConnection connection = myuUrl.openConnection();
connection.connect();
inputStream = connection.getInputStream();
fileSize = connection.getContentLength();

if(fileSize <= 0){
// message.what = 0;
// handler.sendMessage(message);
return "文件为空";
}else{
downloadFile.setFileName(fileName);
downloadFile.setFileSize(fileSize);
downloadFile.setDownLoadAddress(url);
downloadFile.setDownloadState("下载");
outputStream = new FileOutputStream(path +"/"+ fileName);
//存储文件
byte buf[] = new byte[1024];
int len = 0;
int temp = 0;

while ((len = inputStream.read(buf)) != -1) {
if (! isDown) {
outputStream.write(buf, 0, len);
temp += len;
Log.d("skfsk", "sjfsj="+"下载");
downloadFile.setDownloadSize(temp);
fileMap.put(fileName, downloadFile);
// publishProgress((int) (downloadFile.getDownloadSize()*1.0/downloadFile.getFileSize()* 100));
}else {
Log.d("skfsk", "sjfsj="+"暂停下载");
//return "暂停下载";

}
}
}
} catch (Exception e) {

return "出错了";
}finally{
try {

if(inputStream != null || outputStream != null){
outputStream.close();
inputStream.close();
}
} catch (Exception e2) {
}
}

}

return "下载完成";
}


}








package com.mw.guahu.activity.my.download;






import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;


import com.mw.guahu.R;
import com.mw.guahu.activity.BaseActivity;
import com.mw.guahu.activity.ContentActivity;
import com.mw.guahu.activity.createentry.CommentsActivity.ViewHolder;
import com.mw.guahu.activity.widget.CircleImageView;
import com.mw.guahu.activity.widget.InitImageLoder;


import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.Toast;


/*
 * 下载
 */


public class DownLoadActivity extends  BaseActivity{
private ListView listView;
private Map<String, DownloadFile> fileMap;
private List<DownloadFile> downloadFiles;
private FileAdapter fileAdapter;
private TimerTask task;

private Timer timer = new Timer();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_download);
initUI();
task = new TimerTask() {
       public void run() {
           // TODO Auto-generated method stub
           Message message = new Message();
           message.what = 1;
           handler.sendMessage(message);
       }
    };
    timer.schedule(task, 2000, 2000);
}


public void initUI()
{
downloadFiles=new ArrayList<DownloadFile>();
listView=(ListView) findViewById(R.id.listView);
fileMap=((MyApplication)getApplication()).getFileMap();
if(fileMap.size()==0 || fileMap==null)
{
Toast.makeText(getApplicationContext(), "lkj", Toast.LENGTH_SHORT).show();
}else{

Iterator it = fileMap.keySet().iterator(); 
  while (it.hasNext()){ 
   String key; 
   key=(String)it.next(); 
   Log.i("filename", fileMap.get(key).getFileName());
   downloadFiles.add(fileMap.get(key)); 

fileAdapter=new FileAdapter(this, downloadFiles);
listView.setAdapter(fileAdapter);
}
}

Handler handler=new Handler(){


@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub

super.handleMessage(msg);
switch (msg.what) {
case 1:
if(fileAdapter != null)
{
fileAdapter.notifyDataSetChanged();
}


break;
case 2:

break;
case 3:

break;

default:
break;
}

}

};
}





package com.mw.guahu.activity.my.download;


public class DownloadFile {


public int id;
public String fileName;
public String downLoadAddress;
public int fileSize;
public String downloadState;
public int downloadSize;

public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getDownLoadAddress() {
return downLoadAddress;
}
public void setDownLoadAddress(String downLoadAddress) {
this.downLoadAddress = downLoadAddress;
}
public int getFileSize() {
return fileSize;
}
public void setFileSize(int fileSize) {
this.fileSize = fileSize;
}
public String getDownloadState() {
return downloadState;
}
public void setDownloadState(String downloadState) {
this.downloadState = downloadState;
}
public int getDownloadSize() {
return downloadSize;
}
public void setDownloadSize(int downloadSize) {
this.downloadSize = downloadSize;
}


}





package com.mw.guahu.activity.my.download;


import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;






import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.Log;






public class DownLoadThread extends Thread {


private String fileName;
private String downUrl;
private int downSize;
private int fileSize;
private Context mContext;

    public DownLoadThread(String downFileName,String downUrl,Context mContext)
{
this.fileName=downFileName;
this.downUrl=downUrl;
this.mContext=mContext;
}








}







package com.mw.guahu.activity.my.download;




import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;


import android.R.integer;
import android.R.string;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;


public class DownUtil {


//单线程下载目录
public static String path1 = "/down1/";
public static String savePath1;
//多线程下载目录
public static String path2 = "/down2/";
public static String savePath2;

public static String fileName;
public static int fileSize;
public static int fileSize2;

private static int curPosition;
//已下载的文件大小
public static int downLoadSize;
//标示当前线程是否下载完成
public static boolean finished = false;
/**
* 判断sd卡是否存在
* Environment.MEDIA_MOUNTED 判断SD卡是否存在
* @return
*/
public static boolean isExistSdCard(){
boolean flag = true;
if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
flag = false;
}
return flag;
}
/**
* 创建目录
* @param dir
* @return
*/
public static boolean creatDir(String dir){
boolean flag = false;
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + dir);
if(!file.exists()){
file.mkdir();
if(file.exists()){
flag = true;
savePath1 = file.getAbsolutePath();
savePath2 = file.getAbsolutePath();
}
}else{
flag = true;
savePath1 = file.getAbsolutePath();
savePath2 = file.getAbsolutePath();
}
return flag;
}
/**
* 检查网络是否可用
* @return
*/
public static boolean checkNet(Context context){
boolean flag = false;
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(context.CONNECTIVITY_SERVICE);
NetworkInfo wifi = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
NetworkInfo mobile = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if(wifi.isConnectedOrConnecting() || mobile.isConnectedOrConnecting()){
flag = true;
}
return flag;
}
/**
* 单线程文件下载
* @param url
* @param path
*/
public static void fileDown1(String url,String path,Handler handler) {
Log.v("=path=", path+"=");
Message message = new Message();
if(!"".equals(url)){
fileName = url.substring(url.lastIndexOf("/") + 1);
InputStream inputStream = null;
FileOutputStream outputStream = null;
try {
URL myuUrl = new URL(url);
URLConnection connection = myuUrl.openConnection();
connection.connect();
inputStream = connection.getInputStream();
fileSize = connection.getContentLength();
Log.v("=fileSize=", DownUtil.fileSize+"=");
if(fileSize <= 0){
message.what = 0;
handler.sendMessage(message);
return;
}else{
outputStream = new FileOutputStream(path +"/"+ fileName);
//存储文件
byte buf[] = new byte[1024];
int len = 0;
int temp = 0;
Log.v("=available=", inputStream.available()+"=");
while ((len = inputStream.read(buf)) != -1) {
outputStream.write(buf, 0, len);
temp += len;
Message message2 = new Message();
message2.what = 1;
message2.obj = temp;//下载的百分比
handler.sendMessage(message2);
}
Message msg = new Message();
//通知下载完成
msg.what = -1;
msg.obj=fileSize+"";
handler.sendMessage(msg);
}
} catch (Exception e) {
message.what = 2;
handler.sendMessage(message);
return;
}finally{
try {

if(inputStream != null || outputStream != null){
outputStream.close();
inputStream.close();
}
} catch (Exception e2) {
}
}
}
}
/**
* 多线程下载文件
* @param url
* @param path
* @param handler
*/
public static void fileDown2(String url,File file,int startPosition,int endPosition,Handler handler){
URLConnection connection = null;
InputStream inputStream = null;
BufferedInputStream bis = null;
RandomAccessFile raf = null;
try {
URL url2 = new URL(url);
connection = url2.openConnection();
// connection.connect();
connection.setAllowUserInteraction(true);
// 设置当前线程下载的起点,终点
connection.setRequestProperty("Range", "bytes=" + startPosition + "-"
+ endPosition);
inputStream = connection.getInputStream();
if(fileSize2 <= 0){
return;
}
//对文件进行随机读写操作
raf = new RandomAccessFile(file,"rw");
//设置开始写文件的位置
raf.seek(startPosition);
bis = new BufferedInputStream(inputStream);
//开始循环以流的形式读写文件
// curPosition = startPosition;
//每个线程需要读取文件的长度
// int temp = endPosition - startPosition;
byte[] buffer = new byte[1024];
int length = 0;
while ((length = inputStream.read(buffer)) != -1) {
raf.write(buffer, 0, length);
downLoadSize += length;
Message message = new Message();
message.what = 10;
message.obj = downLoadSize;
handler.sendMessage(message);
}
// while (curPosition < endPosition) {
// int len = bis.read(buffer, 0, temp);
// if(len == -1){
// break;
// }
// Log.v("=len=", "="+len);
// raf.write(buffer, 0, len);
// curPosition += len;
if(curPosition > endPosition){
downLoadSize += len - (curPosition - endPosition) + 1;
Log.v("=downLoadSize=", "="+downLoadSize);
}else{
// downLoadSize += len;
}
// Message message = new Message();
// message.what = 10;
// message.obj = downLoadSize;
// handler.sendMessage(message);
// }
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(inputStream != null || raf != null || bis != null){
bis.close();
raf.close();
inputStream.close();
}
} catch (Exception e2) {
}
}
}
}










package com.mw.guahu.activity.my.download;
import java.util.HashMap;
import java.util.Map;




import android.app.Application;




public class MyApplication extends Application {


private Map<String, DownloadFile> fileMap;
public Map<String, DownloadFile> getFileMap() {
return fileMap;
}
public void setFileMap(Map<String, DownloadFile> fileMap) {
this.fileMap = fileMap;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
fileMap=new HashMap<String, DownloadFile>();
}
}









<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?color_more_background" >


    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="17dp"
        android:layout_marginRight="17dp"
        android:background="@drawable/more_item_background" >


     


        <LinearLayout
            android:id="@+id/linearLayout1"
            android:layout_width="263dp"
            android:layout_height="wrap_content"
            android:layout_marginRight="17dp"
            android:layout_toRightOf="@id/imageView"
            android:gravity="center_vertical"
            android:orientation="vertical" >


            <TextView
                android:id="@+id/titleTextView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:layout_marginTop="17dp"
                android:singleLine="true"
                android:text=""
                android:textColor="#2a2a2a"
                android:textSize="16sp"
                 />


     
            <ProgressBar
                android:id="@+id/progressBar1"
                style="?android:attr/progressBarStyleHorizontal"
                android:layout_width="match_parent"
                android:layout_height="5dp" />


            <TextView
                android:id="@+id/dames"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="17dp"
                android:layout_marginTop="10dp"
                android:gravity="left"
                android:text=""
                android:textColor="#a2a2a2"
                android:textSize="10sp" />
        </LinearLayout>


             <TextView
                 android:id="@+id/pause_load"
                 android:layout_width="46dp"
                 android:layout_height="27dp"
                 android:layout_alignParentRight="true"
                 android:layout_centerVertical="true"
                 android:layout_marginRight="10dp"
                 android:background="@drawable/classify_seacher"
                 android:clickable="true"
                 android:gravity="center"
                 android:text="下载"
                 android:textColor="?color_main_bottom_textView"
                 android:textSize="12sp" />


    </RelativeLayout>


</RelativeLayout>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: C语言实现FTP断点续传是一项比较复杂的任务,需要对FTP协议有深刻的理解和对C语言编程的熟练掌握。 首先,需要在客户端实现文件的上传和下载功能,并保留上传或下载过程中的文件偏移量,以便进行断点续传。在上传或下载过程中,如果出现中断或错误,可以通过记录文件偏移量和已上传或已下载的字节数来恢复续传。 其次,需要在FTP服务器端实现断点续传的支持。FTP服务器需要提供REST命令,该命令用于设置文件传输的起始偏移量。当客户端发起断点续传的请求时,服务端需要根据请求中记录的文件偏移量和已上传或下载的字节数,调用REST命令设置传输起始偏移量,以便从上一次中断的位置继续传输文件。 最后,需要在客户端和服务器端加入对传输进度的监控和日志记录,以便在发生错误或中断时能够更方便地找到原因,并进行相应的处理。 总的来说,FTP断点续传的实现需要在客户端和服务器端都进行相应的编码,需要对FTP协议及其相关命令有足够的理解,并需要细致地处理各种异常情况,才能保证传输的准确性和可靠性。 ### 回答2: FTP (File Transfer Protocol) 是一种用于在计算机网络间传输文件的标准协议,而断点续传则是指在传输中断后恢复传输时只需要传输未完成的部分,而不必重新传输整个文件。在 C 语言中实现 FTP 断点续传需要以下步骤: 1. 连接 FTP 服务器:使用 socket 函数创建一个连接到 FTP 服务器的 socket,然后使用 connect 函数连接到 FTP 服务器的 IP 地址和端口号。 2. 登录 FTP 服务器:使用 send 函数发送用户和密码信息到 FTP 服务器,以实现登录到 FTP 服务器。 3. 选择目录和文件:使用 send 函数发送要上传或下载的文件名和文件路径,以实现选择目录和文件。 4. 初始化传输:使用 send 函数发送 REST(Resume Transfer)命令和文件偏移量信息,以初始化传输。 5. 开始传输:使用 send 和 recv 函数进行文件传输,并在过程中记录已传输的字节数和剩余的字节数,以支持断点续传。 6. 传输结束:使用 send 函数发送 QUIT 命令以退出 FTP 服务器。 以上是使用 C 语言实现 FTP 断点续传的基本步骤,其中还需要考虑一些细节问题,如错误处理、超时设置、文件传输模式等。同时,为了实现更高效的 FTP 断点续传,还需要使用多线程或者异步 I/O 等技术,以提高传输速度和可靠性。 ### 回答3: FTP是文件传输协议,而断点续传指的是在文件传输过程中,若传输中断,可以不需要重新传输整个文件,而是从中断的地方继续传输,以减少传输时间和流量的浪费。在C语言中,实现FTP断点续传的方法如下: 1. 建立FTP连接 使用socket库中的函数建立客户端与FTP服务器的连接,例如使用socket函数创建一个套接字,然后使用connect函数连接到FTP服务器。 2. 读取文件指针位置 在传输时可以使用ftell函数获取当前文件指针位置,用于记录上一次传输的位置。 3. 断点传输 若传输过程中出现中断,可以通过记录的上一次文件指针位置开始传输,使用fseek函数将文件指针移动到上一次读取的位置,接着继续使用send或recv函数进行文件传输。 4. 传输完成 当文件传输完成时,关闭FTP连接,释放套接字。 需要注意的是,FTP断点续传需要服务器端支持断点续传,即在FTP服务器端需要开启断点续传的相关支持,否则客户端进行断点续传也无法成功。而且,在进行断点续传过程中,需要保证文件的一致性和完整性,防止数据被篡改或重复传输,因此还需要进行文件校验和验证。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值