`
zqb666kkk
  • 浏览: 732514 次
  • 性别: Icon_minigender_1
  • 来自: 宁波
社区版块
存档分类
最新评论

多线程下载文件

    博客分类:
  • java
 
阅读更多
package mutiDownload;

import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * 多线程下载文件
 * @author Administrator
 *
 */
public class Demo {

	
	public final static int threadcount=3;
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		
		//获取服务器上的文件长度,在本地创建一个和服务器上的文件一样大的临时文件
		String pathString="http://192.168.1.84:8091/androidServer/test.mkv";
		URL url=new URL(pathString);
		HttpURLConnection connection=(HttpURLConnection) url.openConnection();
		connection.setConnectTimeout(5000);
		connection.setRequestMethod("GET");
		int code=connection.getResponseCode();
		if(code==200){	//请求成功
			int length=connection.getContentLength();
			System.out.println("文件长度:"+length);
			RandomAccessFile ref=new RandomAccessFile("test.mkv","rwd");
			//指定创建的临时文件的长度
			ref.setLength(length);
			ref.close();
			
			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 Downhread(threadId, startIndex, endIndex, pathString).start();;
				
			}
		}else{
			System.out.println("服务器错误");
		}
		
	}
	
	/**
	 * 下载文件子线程
	 * @author Administrator
	 *
	 */
	public static class Downhread  extends Thread {
		private int threadId;
		private int startIndex;
		private int endIndex;
		private String path;
		
		

		/**
		 * 
		 * @param threadId	线程id
		 * @param startIndex	线程下载的开始位置
		 * @param endIndex
		 * @param path	下载文件在服务器上的位置
		 */
		public Downhread(int threadId, int startIndex, int endIndex, String path) {
			super();
			this.threadId = threadId;
			this.startIndex = startIndex;
			this.endIndex = endIndex;
			this.path = path;
		}




		@Override
		public void run() {
			// TODO Auto-generated method stub
			//super.run();
			try {
				URL url=new URL(path);
				HttpURLConnection connection=(HttpURLConnection) url.openConnection();
				connection.setConnectTimeout(5000);
				connection.setRequestMethod("GET");
				connection.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);
				int code=connection.getResponseCode();
				System.out.println("code:"+code);
//				if(code==200){	//请求成功
//					
//				}
				InputStream is=connection.getInputStream();
				RandomAccessFile raf=new RandomAccessFile("test.mkv","rwd");
				//写文件的时候指定从哪个位置开始写
				raf.seek(startIndex);
				
				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+"下载完毕了...");
				
			} catch (MalformedURLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}
1
1
分享到:
评论
4 楼 zqb666kkk 2014-09-23  
liujiafei_2007 写道
RandomAccessFile ref=new RandomAccessFile("test.mkv","rwd"); 
//指定创建的临时文件的长度 
ref.setLength(length); 
ref.close();
你好,请问main方法中的这三行有什么作用呢?




RandomAccessFile("test.mkv","rwd");   //

RandomAccessFile

public RandomAccessFile(File file,
                        String mode)
                 throws FileNotFoundException
创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定。将创建一个新的 FileDescriptor 对象来表示此文件的连接。
mode 参数指定用以打开文件的访问模式。允许的值及其含意为:



含意

"r" 以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。
"rw" 打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。
"rws" 打开以便读取和写入,对于 "rw",还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备。
"rwd"  打开以便读取和写入,对于 "rw",还要求对文件内容的每个更新都同步写入到底层存储设备。
"rws" 和 "rwd" 模式的工作方式极其类似 FileChannel 类的 force(boolean) 方法,分别传递 true 和 false 参数,除非它们始终应用于每个 I/O 操作,并因此通常更为高效。如果该文件位于本地存储设备上,那么当返回此类的一个方法的调用时,可以保证由该调用对此文件所做的所有更改均被写入该设备。这对确保在系统崩溃时不会丢失重要信息特别有用。如果该文件不在本地设备上,则无法提供这样的保证。
"rwd" 模式可用于减少执行的 I/O 操作数量。使用 "rwd" 仅要求更新要写入存储的文件的内容;使用 "rws" 要求更新要写入的文件内容及其元数据,这通常要求至少一个以上的低级别 I/O 操作。

如果存在安全管理器,则使用 file 参数的路径名作为其参数调用它的 checkRead 方法,以查看是否允许对该文件进行读取访问。如果该模式允许写入,那么还使用该路径参数调用该安全管理器的 checkWrite 方法,以查看是否允许对该文件进行写入访问。

                             -----引自jdk 1.6api

其实上面这三个主要是迅雷的下载原理  就是下载之前 先在本地创建一个和服务器上一样大的临时文件  并且指定 随机访问文件的操作权限 为 rwd 然后做完这一步后关闭此随机访问文件流并释放与该流关联的所有系统资源
3 楼 zqb666kkk 2014-09-23  
cywhoyi 写道
挺好的多线程案例,我想询问以下几个问题,如果不对之处,望谅解
1.其实这样length分开略显不公平,譬如中华人民共和国1234567,其实前者thread的io消耗更大
2.看得出来是用来爬数据用,因为主线和子线都是同步,是否对于cpu\memory要求很高,是否模拟用异步任务来
3.每个线程其实都是独立分开的,在写文件时候,如何保证是append的?



下载的时候三个线程 各自负责一个区域   三个区域拼成一个完整的文件
2 楼 cywhoyi 2014-09-22  
挺好的多线程案例,我想询问以下几个问题,如果不对之处,望谅解
1.其实这样length分开略显不公平,譬如中华人民共和国1234567,其实前者thread的io消耗更大
2.看得出来是用来爬数据用,因为主线和子线都是同步,是否对于cpu\memory要求很高,是否模拟用异步任务来
3.每个线程其实都是独立分开的,在写文件时候,如何保证是append的?
1 楼 liujiafei_2007 2014-09-22  
RandomAccessFile ref=new RandomAccessFile("test.mkv","rwd"); 
//指定创建的临时文件的长度 
ref.setLength(length); 
ref.close();
你好,请问main方法中的这三行有什么作用呢?

相关推荐

    C#实现多线程下载文件

    通过上述步骤,我们可以实现一个高效的多线程文件下载器。这个过程涉及到的知识点包括:线程与线程池、异步编程、文件I/O、HTTP范围请求、异常处理和进度更新。这些知识对于任何希望深入理解C#并发编程和网络编程的...

    SpringBoot版本的多线程下载文件,分段下载文件

    首先,多线程下载文件是一种提高下载速度的方法,通过将大文件分成多个小部分,每个部分由一个单独的线程负责下载,从而充分利用多核处理器的并行处理能力。在Java中,我们可以使用`java.util.concurrent`包中的`...

    android多线程下载文件

    在Android开发中,多线程下载文件是一种常见的优化策略,特别是在处理大文件或者网络环境不稳定的情况下,能够提高下载效率并减少资源浪费。本项目提供的就是一个实现了多线程断点续传功能的Android下载器,它包含...

    java实现多线程下载文件

    通过以上步骤,我们可以设计并实现一个高效的多线程文件下载系统。在实际项目中,还可以考虑使用成熟的库,如Apache HttpClient或OkHttp,它们提供了对多线程下载的良好支持。同时,结合Java的并发库,可以构建出更...

    Android多线程下载文件

    在Android应用开发中,多线程下载文件是一个常见的需求,特别是在处理大文件或者需要优化用户体验时。这个场景中,我们采用多线程技术来提高下载效率,并且支持断点续传功能,这意味着如果下载过程中因网络问题中断...

    可以多线程下载文件的c++客户端

    可以多线程下载文件c++的客户端软件,可以切割文件并传输

    C#多线程下载文件源码

    在C#编程中,多线程技术是一种提升应用程序性能的有效方式,特别是在处理耗时操作如文件下载时。本文将深入探讨如何使用C#实现多线程下载文件,并基于提供的源码进行分析和学习。 首先,多线程的概念是并发执行多个...

    C# 多线程下载文件

    在C#编程中,多线程技术是一种提升应用程序性能的有效方式,特别是在处理耗时操作如大文件下载时。本文将深入探讨如何利用C#实现多线程下载文件,并结合给出的"多线程下载文件"项目,理解其工作原理。 首先,让我们...

    多线程分别下载文件

    这个"多线程分别下载文件"的Demo是针对在ListView或GridView控件中实现的一项功能,允许用户选择多个文件进行并行下载,并且每个文件的下载进度可以在对应的列表项中实时更新,提供良好的用户体验。 首先,我们要...

    Android多线程下载文件实例

    在Android应用开发中,多线程技术是必不可少的,特别是在处理耗时操作,如网络请求、文件下载等场景。本文将深入探讨如何在Android中实现多线程下载文件的实例。 首先,我们要理解多线程的基本概念。在单线程环境中...

    java多线程下载文件

    ### Java多线程断点下载文件:关键技术与实现 在当今高速互联网环境下,高效的数据传输技术变得至关重要。Java多线程断点续传文件下载技术就是一种能够显著提高下载速度和稳定性的方法。本文将深入解析Java多线程...

    qt多线程高效下载文件

    本项目"qt多线程高效下载文件"是基于Qt实现的一个实用工具,它利用多线程技术来提高文件下载的效率,特别是对于大文件或者需要同时下载多个文件的场景,这种多线程策略显得尤为重要。 在HTTP协议方面,它是互联网上...

    关于vb多线程下载文件的例子

    下面我们将详细讲解如何使用VB创建一个简单的多线程文件下载程序。 首先,我们需要创建一个新的线程来执行下载任务。在VB中,我们可以创建一个`Thread`对象,并为其传递一个委托(Delegate),这个委托指向要在线程...

    delphi7多线程下载文件

    在Delphi7中,开发多线程下载文件的应用程序是一项技术含量较高的任务,涉及到并发处理、网络通信以及文件I/O等多个方面。在这个场景下,我们通常会利用Indy10库,尤其是其中的IdHTTP组件来实现网络请求,再结合多...

    htp多线程断点下载文件

    在IT领域,网络数据传输是不可或缺的一部分,而断点续传和多线程下载技术则大大提升了文件下载的效率和用户体验。"htp多线程断点下载文件"这一主题,涉及了网络编程、多线程技术和文件处理等多个知识点。 首先,...

    多线程实现文件下载,代码规范明了

    在多线程文件下载中,我们可以为每个线程创建一个Socket,分别与服务器保持连接,实现文件的分块下载。 2. HTTP:超文本传输协议是互联网上应用最广泛的一种网络协议。HTTP支持断点续传功能,非常适合大文件的下载...

    java多线程下载文件源码

    在Java编程中,多线程下载文件是一种优化大文件下载效率的技术。它通过将一个大文件分割成多个小部分,然后在不同的线程中并行下载这些部分,从而充分利用网络带宽,加快下载速度。本源码实现了这样一个功能,让下载...

    Python3中的单线程带进度条和多线程下载文件代码及注意事项

    写一个多线程分块下载文件工具。网上的一些代码可能会有些奇怪的问题,用的是类全局变量打开文件但在多线程中并未加锁,会导致文件有一定几率出现大小和源文件不同,即使文件大小相同,MD5值也不同,中间有一段是坏的...

    C# Winform 多线程下载

    在C# Winform应用中实现多线程下载是一项常见的任务,尤其在处理大文件或需要提高下载速度的情况下。本文将详细讲解如何利用C#的多线程技术来创建一个Winform应用程序,实现高效的文件下载功能。 首先,我们需要...

Global site tag (gtag.js) - Google Analytics