负责下载的线程:
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
public class DownloadThread extends Thread {
// 定义字节数组(用于取水的那个竹筒)的长度
private final int BUFF_LEN = 100;
// 定义下载的起始点
private long start;
// 定义下载的结束点
private long end;
// 下载资源对应的输入流
private InputStream inputStream;
// 下载资源对应的输出流
private RandomAccessFile randomAccessFile;
// 构造器:传入起始下载点,结束下载点,输入流,输出流
public DownloadThread (long start,long end,InputStream inputStream,RandomAccessFile randomAccessFile) {
// 打印一下该线程的起始下载点和结束下载点的位置信息
System.out.println(start+" >------> "+end);
this.start = start;
this.end = end;
this.inputStream = inputStream;
this.randomAccessFile = randomAccessFile;
}
@Override
public void run() {
try {
// 记录指针向前移动start个字符
inputStream.skip(start);
// 记录指针定位到start位置处
randomAccessFile.seek(start);
// 定义读取输入流内容的缓存数组(竹筒)
byte[] buff = new byte[BUFF_LEN];
// 本线程负责下载的资源大小
long contentLen = end - start;
// 定义最多需要几次就可以完成本线程的下载任务,方便控制线程的退出
long readMaxTimes = contentLen/BUFF_LEN + 4;
// 实际读取的字节数
int reallyReadCount = 0;
for (int i = 0; i < readMaxTimes; i++) {
// 读取数据
reallyReadCount = inputStream.read(buff);
// 如果读取的字节数小于0,说明读取完毕,则退出循环
if (reallyReadCount < 0) {
break;
}
// 写入数据
randomAccessFile.write(buff, 0, reallyReadCount);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 使用finally块来关闭当前线程的输入流和输出流
try {
if (inputStream != null) {
inputStream.close();
}
if (randomAccessFile != null) {
randomAccessFile.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
传入Url地址,开启下载:
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class MultiDownload {
public static void main(String[] args) {
// 定义开启的线程数
final int DOWNLOAD_THREAD_NUM = 4;
// 定义下载文件的文件名,包括后缀
final String OUTPUT_FILE_NAME = "baidu.gif";
// 定义一个DOWNLOAD_THREAD_NUM大小的输入流数组
InputStream[] inArrays = new InputStream[DOWNLOAD_THREAD_NUM];
// 定义一个DOWNLOAD_THREAD_NUM大小的输出流数组
RandomAccessFile[] outArrays = new RandomAccessFile[DOWNLOAD_THREAD_NUM];
try {
// 创建一个URL对象,参数是我们要下载的资源的地址
URL downloadUrl = new URL("http://www.baidu.com/img/baidu_sylogo1.gif");
// 以该URL对象打开第一个输入流
inArrays[0] = downloadUrl.openStream();
// 获取该网络资源文件的长度
long fileLength = getFileLength(downloadUrl);
// 做一个打印
System.out.println("该网络资源文件的大小:"+fileLength);
// 以输出的文件名创建第一个输出流对象,模式是可读,可写
outArrays[0] = new RandomAccessFile(OUTPUT_FILE_NAME, "rw");
// 创建一个与下载资源文件相同大小的空文件
for (int i = 0; i < fileLength; i++) {
outArrays[0].write(0);
}
// 计算每个线程应该下载的字节数
long everyThreadDownloadSize = fileLength/DOWNLOAD_THREAD_NUM;
// 计算整个下载资源整除后剩下的余数
long otherDownloadSize = fileLength%DOWNLOAD_THREAD_NUM;
// 启动各个线程下载各自规定的读取长度的资源
for (int i = 0; i < DOWNLOAD_THREAD_NUM; i++) {
// 刚才只初始化了第一个输入流和输出流对象,初始化剩下的输入流和输出流对象
if (i != 0) {
inArrays[i] = downloadUrl.openStream();
outArrays[i] = new RandomAccessFile(OUTPUT_FILE_NAME, "rw");
}
// 独立配置最后一个线程的下载参数(该线程负责下载整除后余下的资源)
if (i == DOWNLOAD_THREAD_NUM -1) {
new DownloadThread(i*everyThreadDownloadSize, (i+1)*everyThreadDownloadSize+otherDownloadSize, inArrays[i], outArrays[i]);
} else {
// 配置前几个线程的下载参数
new DownloadThread(i*everyThreadDownloadSize, (i+1)*everyThreadDownloadSize, inArrays[i], outArrays[i]);
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
// 根据URL获取该URL所指向的资源文件的长度
private static long getFileLength(URL url) throws IOException{
long length = 0;
URLConnection urlConnection = url.openConnection();
long size = urlConnection.getContentLength();
length = size;
return length;
}
}
分享到:
相关推荐
Java编写的多线程下载程序源码是一种利用Java语言特性实现高效大文件下载的技术。在这一程序中,主要涉及到了Java的多线程处理和网络编程两大核心知识点。 首先,让我们深入理解Java的多线程。Java提供了丰富的多...
在Java编程中,多线程下载文件是一种...通过学习这个源码,你可以深入了解如何在Java中实现实用的多线程下载功能,同时也可以提高对并发编程的理解和实践能力。对于大型项目或高并发应用来说,这样的技术是不可或缺的。
Java多线程下载是利用Java编程语言实现的一种高效下载大文件的技术。在传统的单线程下载方式中,如果网络环境不稳定或文件较大,下载过程可能会很慢,甚至中断。而多线程下载则是将文件分割成多个部分,每个部分由一...
其设计和实现充分考虑了效率、稳定性和用户体验,是学习和研究Java多线程技术的一个优秀实例。通过分析和研究这个源码,开发者不仅可以加深对Java编程的理解,还能掌握多线程下载工具的开发技巧,为自己的项目开发...
Java多线程下载课程设计是一项常见且实用的项目,它涉及到计算机网络、操作系统以及Java编程语言的核心特性。在这个工程源码中,开发者可能利用了Java的并发能力来提高下载效率,实现了多线程同时下载文件的不同部分...
根据提供的文件信息,我们可以梳理出一个使用Java进行网络文件多线程下载的实现方案。下面将详细介绍相关的知识点。 ### Java线程下载网络文件原理 在Java中,通过多线程技术可以有效地提高文件下载的速度。具体来...
通过分析和实践这个"Java+多线程下载源代码学习"项目,你可以深入理解Java多线程编程的细节,增强在实际项目中应用多线程的能力。同时,这也是提升并发编程技能,解决复杂问题的良好实践。记得查看`下载及使用说明....
通过对Leo2005源码的学习,开发者不仅可以掌握多线程编程,还能了解到网络编程、文件操作、同步机制等多个领域的知识。通过实际分析和实践,可以加深对这些技术的理解,为今后的项目开发提供宝贵的经验。
多线程则是并发处理的一种方式,它允许多个任务或数据块同时下载,从而提高下载速度,特别是对于大文件,能显著减少下载时间。 【描述】提到这是作者自己编写的,并愿意分享源码,这为学习者提供了一个实践和研究的...
在Java编程中,实现HTTP多线程下载是一项常见的任务,特别是在处理大文件或者需要提高下载速度的情况下。这个过程涉及到并发编程、网络I/O以及文件操作等多个领域的知识。下面,我们将详细探讨如何使用Java来实现这...
通过阅读提供的"Java多线程设计模式详解.pdf"和"Java多线程设计模式上传文件",开发者可以深入学习这些模式的原理、实现方式以及实际应用场景,从而在实际工作中更好地运用多线程设计模式,提升软件的并发性能和质量...
Java编写的多线程下载器是一个实用的工具,它利用Java编程语言的特性,特别是多线程和Swing库,来实现高效的文件下载功能。在这个项目中,开发者创建了一个用户友好的界面,允许用户自定义下载设置,如启用的线程数...
客户端可能只有一个线程,但根据具体需求,也可能设计为多线程,比如并发下载或者上传文件。 学习这个源码,我们可以深入理解Java的网络编程和多线程机制,包括线程的创建、同步、通信等概念。此外,还可以了解到...
Java仿迅雷多线程下载工具的实现涉及到了断点续传技术和HTTP及FTP协议的运用,这两种协议在文件传输中扮演着重要角色。断点续传技术允许在下载或上传过程中因网络中断而从上次停止的地方继续,极大地提高了效率和...
这个名为"java多线程源码,仅供参考"的压缩包文件,显然是为了帮助学习者深入理解Java多线程的运行机制。其中的示例程序"BounceThread"可能是一个演示线程交互和同步的经典案例,常用于教授线程的创建、运行以及线程...
总之,"MulThreadDownload"源码提供了实现多线程下载的实例,涵盖了多线程编程、文件I/O、网络通信和并发控制等多个Java编程的关键知识点。通过学习和分析这个项目,开发者不仅可以掌握多线程下载技术,还能提升在...
总之,多线程下载软件Java源码是一个综合性的学习案例,涵盖了Java多线程、网络编程、文件I/O和同步控制等多个重要知识点。通过分析和理解这个实例,开发者可以提升对Java并发编程的理解,为实际项目开发打下坚实...
总结来说,这个实验源码涵盖了Java多线程的基础和应用,包括线程的创建、运行、同步、通信,以及网络编程和数据库操作。通过这些实验,学生可以深入理解Java并发编程的核心概念,并掌握实际开发中的多线程设计技巧。
1. **Java多线程基础**:Java提供了两种创建线程的方式:继承Thread类和实现Runnable接口。在Web服务器源码中,通常会采用后者,因为这样可以避免单继承的限制,提高代码的可扩展性。 2. **Socket编程**:Web服务器...