-
实现多线程下载同一个文件
2016-03-18 19:01:52Java实现多线程下载同一个文件原理:
示例代码:
public class LoadFile { private static int threadCount = 3;// 下载的线程数量 public static void main(String[] args) { // 1、与服务器建立连接,获得文件的大小,在本地创建一个与需下载文件同等大小的临时文件 String path = "http://localhost/safe.exe"; try { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setReadTimeout(5000); int code = conn.getResponseCode(); if(200 == code) { // 获得文件的长度 int length = conn.getContentLength(); System.out.println("文件总长度为:"+length); // 在本地创建一个可以随机读取的与源文件同等大小的临时文件 RandomAccessFile raf = new RandomAccessFile("safe.exe", "rwd"); // 指定文件的长度 raf.setLength(length);// 设置文件长度 raf.close(); // 2、实现多线程下载资源 int blockSize = length / threadCount ;// 每个线程平均需要下载文件的大小 for(int threadId = 1; threadId <= threadCount; threadId++) { // 每个线程下载文件的初始位置和结束位置 int startIndex = (threadId-1) * blockSize; int endIndex = threadId * blockSize - 1; // 下载的最后一块的情况 if(threadCount == threadId) { endIndex = length - 1;// 如果不减1的话,就超出了文件的范围 } System.out.println("线程 "+threadId+"下载位置为:"+startIndex+"--->"+endIndex); // 启动下载线程 new DownloadThread(path, startIndex, endIndex, threadId).start(); } } else { System.out.println("服务器出现错误"); } } catch (Exception e) { System.out.println("连接服务器URL出现错误"); e.printStackTrace(); } } }
public class DownloadThread extends Thread { private String path;// 服务器路径 private int startIndex;// 块文件开始位置 private int endIndex;// 快文件结束位置 private int threadId;// 线程编号 public DownloadThread() { } public DownloadThread(String path, int startIndex, int endIndex, int threadId) { this.path = path; this.startIndex = startIndex; this.endIndex = endIndex; this.threadId = threadId; } @Override public void run() { try { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setReadTimeout(5000); // 提交请求可以从指定位置读取文件 conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex); int code = conn.getResponseCode(); // 请求全部文件成功返回200, 请求部分文件成功返回206 if (206 == code) { RandomAccessFile raf = new RandomAccessFile("safe.exe", "rwd"); // 随机文件从哪里读 raf.seek(startIndex);// 定位文件 InputStream is = conn.getInputStream(); int len = 0; byte[] buffer = new byte[1024]; while ((len = is.read(buffer)) != -1) { raf.write(buffer, 0, len); } is.close(); raf.close(); System.out.println("线程" + threadId + "下载完毕!!!!"); } else { System.out.println("线程"+threadId+"请求的部分资源失败"); } } catch (Exception e) { System.out.println("下载线程的URL连接异常"); e.printStackTrace(); } } }
// 别下载太大的文件,可能等待时间很长 /*Output: 文件总长度为:11556608 线程 1下载位置为:0--->3852201 线程 2下载位置为:3852202--->7704403 线程 3下载位置为:7704404--->11556607 线程2下载完毕!!!! 线程1下载完毕!!!! 线程3下载完毕!!!! */
-
多线程下载同一个文件 c# async await
2019-10-01 18:47:52原计划先生成一个和下载目标同名,同大小的空文件,在下载的同时用filestream 的seek把下载到的各个字节填写进去,可惜总是数据不完整。对async这个模型还不了解。 没办法才用了临时文件这个办法。有懂的就留言告诉... -
java多线程下载同一个文件_使用多线程去下载同一个文件
2021-02-28 14:23:02连接服务器,获取一个文件,获取文件的长度,在本地创建一个跟服务器一样大小的临时文件 11 URL url = newURL(path);12 HttpURLConnection conn =(HttpURLConnection)url.openConnection();13 conn....1 importjava.io.InputStream;2 importjava.io.RandomAccessFile;3 importjava.net.HttpURLConnection;4 importjava.net.URL;5
6 public classDemo {7 public static String path = "http://softdownload.hao123.com/hao123-soft-online-bcs/soft/Y/2013-07-18_YoudaoDict_baidu.alading.exe";
8 public static int threadCount = 3;9 public static void main(String[] args) throwsException{10 //1.连接服务器,获取一个文件,获取文件的长度,在本地创建一个跟服务器一样大小的临时文件
11 URL url = newURL(path);12 HttpURLConnection conn =(HttpURLConnection)url.openConnection();13 conn.setConnectTimeout(5000);14 conn.setRequestMethod("GET");15 int code =conn.getResponseCode();16 if (code == 200) {17 //服务器端返回的数据的长度,实际上就是文件的长度
18 int length =conn.getContentLength();19 System.out.println("文件总长度:"+length);20 //在客户端本地创建出来一个大小跟服务器端一样大小的临时文件
21 RandomAccessFile raf = new RandomAccessFile("setup.exe", "rwd");22 //指定创建的这个文件的长度
23 raf.setLength(length);24 raf.close();25 //假设是3个线程去下载资源。26 //平均每一个线程下载的文件大小.
27 int blockSize = length /threadCount;28 for (int threadId = 1; threadId <= threadCount; threadId++) {29 //第一个线程下载的开始位置
30 int startIndex = (threadId - 1) *blockSize;31 int endIndex = threadId * blockSize - 1;32 if (threadId == threadCount) {//最后一个线程下载的长度要稍微长一点
33 endIndex =length;34 }35 System.out.println("线程:"+threadId+"下载:---"+startIndex+"--->"+endIndex);36 newDownLoadThread(path, threadId, startIndex, endIndex).start();37 }38
39 }else{40 System.out.printf("服务器错误!");41 }42 }43
44 /**
45 * 下载文件的子线程 每一个线程下载对应位置的文件46 *@authorjie47 *48 */
49 public static class DownLoadThread extendsThread{50 private intthreadId;51 private intstartIndex;52 private intendIndex;53 /**
54 *@parampath 下载文件在服务器上的路径55 *@paramthreadId 线程Id56 *@paramstartIndex 线程下载的开始位置57 *@paramendIndex 线程下载的结束位置58 */
59 public DownLoadThread(String path, int threadId, int startIndex, intendIndex) {60 super();61 this.threadId =threadId;62 this.startIndex =startIndex;63 this.endIndex =endIndex;64 }65
66 @Override67 public voidrun() {68 try{69 URL url = newURL(path);70 HttpURLConnection conn =(HttpURLConnection)url.openConnection();71 conn.setConnectTimeout(5000);72 conn.setRequestMethod("GET");73 //重要:请求服务器下载部分文件 指定文件的位置
74 conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);75 //从服务器请求全部资源返回200 ok如果从服务器请求部分资源 返回 206 ok
76 int code =conn.getResponseCode();77 System.out.println("code:"+code);78 InputStream is = conn.getInputStream();//已经设置了请求的位置,返回的是当前位置对应的文件的输入流
79 RandomAccessFile raf = new RandomAccessFile("setup.exe", "rwd");80 //随机写文件的时候从哪个位置开始写
81 raf.seek(startIndex);//定位文件
82
83 int len = 0;84 byte[] buffer = new byte[1024];85 while ((len = is.read(buffer)) != -1) {86 raf.write(buffer, 0, len);87 }88 is.close();89 raf.close();90 System.out.println("线程:"+threadId+"下载完毕");91 } catch(Exception e) {92 e.printStackTrace();93 }94 }95
96 }97 }
-
使用多线程下载同一个文件
2013-11-21 19:06:14理解:将服务器的一个资源分成多个部分,每个线程复制下载其中一个部分,然后设置每个线程对同一个文件开始写入的位置,当所有线程下载完成后,本地文件便是一个完整的文件了。 需要的权限: activity_...理解:将服务器的一个资源分成多个部分,每个线程负责下载其中一个部分,然后设置每个线程对同一个文件开始写入的位置,当所有线程下载完成后,本地文件便是一个完整的文件了。
需要的权限:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:id="@+id/download" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="下载" /> <ProgressBar android:id="@+id/progressBar" style="?android:attr/progressBarStyleHorizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentRight="true" android:layout_alignParentTop="true" /> </RelativeLayout>
MainActivity.java :package com.xie.app; import java.io.BufferedInputStream; import java.io.File; 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.util.ArrayList; import java.util.List; import android.app.Activity; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.AsyncTask; import android.os.Bundle; import android.os.Environment; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ProgressBar; import android.widget.Toast; public class MainActivity extends Activity implements OnClickListener { // 下载按钮 private Button download; // 下载进度条 private ProgressBar progress; // 所有下载任务 private List<MyDownloadTask> tasks; /** 下载地址 */ public static final String URL_DOWNLOAD = "http://192.168.1.104:8080/WebServer/music/handin.ape"; /** 线程数量 */ public static final int TASK_COUNT = 3; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); download = (Button) findViewById(R.id.download); download.setOnClickListener(this); progress = (ProgressBar) findViewById(R.id.progressBar); } @Override public void onClick(View v) { if (v == download) { // 下载 try { URL url = new URL(URL_DOWNLOAD); // 获取资源总长度 int totalLength = url.openConnection().getContentLength(); // 设置进度条总长度 progress.setMax(totalLength); // 每条线程应该下载的长度 int perLength = totalLength % TASK_COUNT == 0 ? totalLength / TASK_COUNT : totalLength / TASK_COUNT + 1; if (Environment.MEDIA_MOUNTED.equals(Environment .getExternalStorageState()) && isHaveConnection()) { // 如果sd卡可用并且网络可用 // 创建文件 File file = new File( Environment.getExternalStorageDirectory(), "handin.ape"); if (file.exists()) { file.delete(); } file.createNewFile(); // 初始化线程分支集合 tasks = new ArrayList<MyDownloadTask>(TASK_COUNT); // 循环创建线程并下载 for (int i = 0; i < TASK_COUNT; i++) { MyDownloadTask task = new MyDownloadTask(perLength * i, perLength * (i + 1), url, file); task.execute(); // 添加进入任务列表中 tasks.add(task); } } else { Toast.makeText(this, "内存卡不可用", Toast.LENGTH_SHORT).show(); } } catch (MalformedURLException e) { } catch (IOException e) { } } } /** * 判断网络是否可用 * * @return true可用 false不可用 */ public boolean isHaveConnection() { ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo info = cm.getActiveNetworkInfo(); if (info != null) { return info.isAvailable(); } return false; } /** * 下载任务 * * @author lx */ class MyDownloadTask extends AsyncTask<Void, Void, Void> { // 开始位置 private int begin; // 结束位置 private int end; // 下载的地址 private URL url; // 保存的文件对象 private File file; public MyDownloadTask(int begin, int end, URL url, File file) { super(); this.begin = begin; this.end = end; this.url = url; this.file = file; } // 当前线程进度情况 private int current; public int getCurrent() { return current; } @Override protected Void doInBackground(Void... params) { try { HttpURLConnection con = (HttpURLConnection) url .openConnection(); // 设置下载区间 con.setRequestProperty("Range", "bytes=" + begin + "-" + end); InputStream in = con.getInputStream(); BufferedInputStream input = new BufferedInputStream(in); // 创建文件输出,"rwd":读写删除权限,其它类型看提示说明 RandomAccessFile output = new RandomAccessFile(file, "rwd"); // 设置开始写入的位置 output.seek(begin); // 单次写的byte数组 byte[] bs = new byte[1024 * 1024]; // 单次写的长度 int length = 0; while ((length = input.read(bs)) != -1) { output.write(bs, 0, length); // 当前分支进度增加 current += length; publishProgress(); } // 关闭,将缓冲区写入文件 input.close(); output.close(); } catch (IOException e) { } return null; } @Override protected void onProgressUpdate(Void... values) { // 当前总进度 int total = 0; for (MyDownloadTask task : tasks) { // 循环获取每一条分支的进度 total += task.getCurrent(); } progress.setProgress(total); super.onProgressUpdate(values); } @Override protected void onPostExecute(Void result) { if (progress.getProgress() == progress.getMax()) { // 判断进度条是否满 Toast.makeText(MainActivity.this, "下载成功!", Toast.LENGTH_SHORT) .show(); } super.onPostExecute(result); } } }
-
多线程下载同一个文件的不同块操作实例
2011-06-02 08:26:541. 支持多线程: 多个线程某时刻下载同一个文件的不同块. 2. 断点续传: 如果下载了一个文件的某些块(一半), 则下次下载时只需下载未完成的块;文件块的下载状态用控制文件记录. 块下载完成的先后顺序不一定是连续的. ... -
多线程下载同一个文件(断点下载)
2019-09-04 22:00:14通过设置Range可以指定每次从网路下载数据包的大小 Range示例 bytes=0-499 从0到499的头500个字节 bytes=500-999 从500到999的第二个500字节 bytes=500- 从500字节以后的所有字节 bytes=-500 最后500个字节 bytes=...HTTP Range的示例 通过设置Range可以指定每次从网路下载数据包的大小 Range示例 bytes=0-499 从0到499的头500个字节 bytes=500-999 从500到999的第二个500字节 bytes=500- 从500字节以后的所有字节 bytes=-500 最后500个字节 bytes=500-599,800-899 同时指定几个范围 Range小结 - 用于分隔前面的数字表示起始字节数,后面的数组表示截止字节数,没有表示到末尾, 用于分组,可以一次指定多个Range,不过很少用 //分段下载文件 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:kTimeout]; NSString *range = [NSString stringWithFormat:@"bytes=%lld-%lld", from, end]; [request setValue:range forHTTPHeaderField:@"Range"]; NSURLResponse *response = nil; NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:NULL]; #pragma mark - 获取网络文件大小 - (long long)fileSizeWithURL:(NSURL *)url { // 默认是GET NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:kTimeOut]; // HEAD 头,只是返回文件资源的信息,不返回具体是数据 // 如果要获取资源的MIMEType,也必须用HEAD,否则,数据会被重复下载两次 request.HTTPMethod = @"HEAD"; // 使用同步方法获取文件大小 NSURLResponse *response = nil; [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:NULL]; // expectedContentLength文件在网络上的大小 NSLog(@"%lld", response.expectedContentLength); return response.expectedContentLength; }
-
多线程下载同一个文件 c# async/await
2019-10-02 10:16:57然同时开启了10个任务进行分段下载(HTTP 1.1支持下载文件的指定部分),以500K的速度完成了下载-,最后把10个临时文件合并起来。不过这个年代估计下载速度已经不是瓶颈了。。。。。 用了两种方法保存... -
使用多线程去下载同一个文件
2016-09-20 16:33:001.连接服务器,获取一个文件,获取文件的长度,在本地创建一个跟服务器一样大小的临时文件 11 URL url = new URL(path); 12 HttpURLConnection conn = (HttpURLConnection)url.openConnection(); 13 conn.... -
[Python]_[初级]_[多线程下载单个文件]
2020-07-18 16:22:36有没有模块类似下载工具那样能多线程下载同一个文件? 如果没有多线程下载单个文件的模块,那我们应该如何编码实现功能? 说明 Python作为日常的部署语言,编写自动化脚本目前看来还是比较方便的,因为它的库... -
python多线程看视频_python多线程下载一个视频教程!PYTHON多线程同步的几种方法...
2021-01-14 04:21:56有3个文件1.txt 2.txt 3.txt 我想利用python多线程同时查看3个文件的内容#-*-coding:utf-8-*-importthreadingdefread(file_uri):withopen(file_uri)asfp:foriinfp.readlines():printfile_uri,ia=threading.Thread... -
网络下载编程的单文件多线程下载和断电续传
2012-11-05 13:28:35这几天需要做一些文件的多线程下载和断点续传的工作,所以在网上整理了一些资料供参考,纯粹为了学习,如...多线程下载同一个文件的原理讲述一下: 1、首先得到要下载的文件的长度,这是通过Http的HEAD命令得 -
Python之FTP多线程下载文件之多线程分块下载文件
2017-05-03 16:46:14Python中的ftplib模块用于对FTP的相关操作,常见的如下载,上传等。使用python从FTP下载较大的文件时,往往比较耗时,如何提高从FTP下载文件的速度呢?...1. 将文件分块,比如我们打算采用20个线程去下载同一个文 -
多线程加上断点下载多个文件文件出现问题了
2015-09-17 07:51:53// 每次读取流里数据之后,同步把当前线程下载的总进度写入进度临时文件中 progressRaf.write((total + "").getBytes()); progressRaf.close(); } System.out.println(filename+"线程" + ... -
python 多线程大文件_如何用python编写大文件的多线程下载
2021-01-13 20:04:52在写爬虫的过程中常常遇到下载大文件的情况,比如说视频之类的。...主要的难点一个是多线程下载的同步问题,另一个是文件中断下载后,再次开始从上次中断的地方继续下载。其实我觉得就这两个问题... -
同时下载同一个文件到多个移动硬盘中速度问题
2018-03-25 11:55:07各位大神: PC多路下载工具,将一个文件同时下载到多个移动硬盘中,多路[开启了多个线程]同时开启下载的时间要比单路开启了下载时间长,请问这个应该如何解决?谢谢 -
socket多线程下载文件
2017-02-11 23:02:23多线程下载的思路是建立多个线程,同时连接到服务器,分别从文件的不同位置开始下载,然后将各自接收到的数据合并到同一个文件中。// 服务器端代码 /*************************************************************... -
axel: 多线程下载工具,下载文件时可以替代curl、wget
2018-11-23 15:32:21支持多线程下载、断点续传,且可以从多个地址或者从一个地址的多个连接来下载同一个文件。适合网速不给力时多线程下载提高下载速度。比如在国内VPS或服务器上下载lnmp一键安装包用Axel就比wget快。options就是下面的... -
多线程处理大文件_多线程下载大文件速度更快的原因,到底是什么?
2020-12-10 07:38:00多线程从网上下载一个大文件为什么要更快(比之单线程)?网上查了有人说“是因为io堵塞的原因,因为网速肯定快不过cpu,单线程单io通道,而多线程多io通道“ 。我理解他的意思是:单线程因为网速慢赶不上cpu的处理... -
多线程小案例-同步下载多个图片
2020-10-22 17:34:35多线程小案例—网络图片下载 第一步–下载commons-io.jar包 commons-io是针对开发IO流功能的工具类库 百度搜索commons-io即可前往官网下载(或直接点击该链接前往官网下载) ...先创建一个文件下载工具类 -
使用ftp,sftp多线程给各省同步文件信息 一
2019-03-20 11:31:42开发环境如果没有ftp 服务器的话,可以下载一个serv-U 挺好用的;运行起来就行一个本地的ftp服务器; 1.需求 给各省根据配置表以ftp或sftp协议的方式,多线程 定时任务 给各省同步所需的数据; 设计表:业务基本... -
Android 文件下载--普通多线程下载
2017-04-06 21:32:33我们都知道使用多线程下载文件可以更快地完成文件的下载,但是为什么呢? 答:因为抢占的服务器资源多,假设服务器最多服务100个用户,服务器中的一个线程 对应一个用户100条线程在计算机中并发执行,由CPU划分时间片... -
多线程下载和断电续传
2012-11-05 13:29:44这几天需要做一些文件的多线程下载和断点续传的工作,所以在网上整理了一些资料供参考,纯粹为了学习,如...多线程下载同一个文件的原理讲述一下: 1、首先得到要下载的文件的长度,这是通过Http的HEAD命令得 -
vs实现tcp多线程_多线程下载大文件速度更快的原因,到底是什么?
2021-01-26 08:35:35多线程从网上下载一个大文件为什么要更快(比之单线程)?网上查了有人说“是因为io堵塞的原因,因为网速肯定快不过cpu,单线程单io通道,而多线程多io通道“ 。我理解他的意思是:单线程因为网速慢赶不上cpu的处理... -
网络蚂蚁与FlashGet的文件多线程下载原理
2006-04-24 15:15:00最近自己写了一个类似网络蚂蚁和FlashGet一样的程序,主要是为了自己能学点东西,不过还好,已经有点样子了,已经实现了类似它们的界面风格和功能,只是里面的下载任务、错误...现在将多线程下载同一个文件的原理讲述 -
android实现多线程下载文件(支持暂停、取消、断点续传)
2021-01-05 12:24:19多线程下载文件(支持暂停、取消、断点续传) 多线程同时下载文件即:在同一时间内通过多个线程对同一个请求地址发起多个请求,将需要下载的数据分割成多个部分,同时下载,每个线程只负责下载其中的一部分,最后将... -
多线程实现ftp 文件下载
2018-11-27 09:39:291 需求: 某个接口的纪录在ftp 服务器上,以类别/日期/时间.来存放文件,而一天可能会产生几百个文件,需要下载...3. ftp 多个读取文件循环读取的时候,经常会出现,第一个文件得到字节流,而后面的文件的字节流都是null... -
java 多线程下载文件并实时计算下载百分比(断点续传)
2019-06-09 19:31:00多线程下载文件 多线程同时下载文件即:在同一时间内通过多个线程对同一个请求地址发起多个请求,将需要下载的数据分割成多个部分,同时下载,每个线程只负责下载其中的一部分,最后将每一个线程下载的部分组装起来... -
Android开发之多线程下载(二)
2016-11-16 13:30:36多线程下载同一个文件: 1. 好处:可以提升下载速度,但是并不是你开启下载的线程越多速度就达到很快,因为最终的线程下载速度还是取决于你的带宽,开启多个线程只能让你和别人同时下载时,你的速度是可以比别人... -
使用CInternetFile多线程下载HTTP服务器上的文件
2011-12-07 23:08:00使用CInternetFile多线程下载HTTP服务器上的文件 在使用CInternetFile多线程下载HTTP服务器上文件的时候,最主要是关注两个问题: 1)下载线程同步的问题 2)如何读取并存储文件的问题 第一个问题...