HttpURLConnection方法之setRequestProperty()浅谈

本文介绍了一种利用多线程实现文件下载的技术方案。通过分析HTTP协议,并使用Java语言中的HttpURLConnection对象,实现了文件被分块并由多个线程同时下载的功能。文章详细解释了如何设置线程数量、计算每个线程负责下载的数据范围以及如何使用RandomAccessFile流将下载的数据保存到本地。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【问题】关于从网上下载一个文件分多个线程同时下载。

主要使用到HttpURLConnection对象的setRequestProperty(String key,String value);

方法简单说一下如何使用,setRequestProperty()方法严格上讲是HttpURLConnection的父类---URLConnection的方法,而URL.openConnection()返回的是一个URLConnection对象,而一般我们都用他的子类HttpURLConnection去做链接和网络传输工作。

【解决思路总述】

1,把指定文件(通过HttpURLConnection.getContentLength();获得文件大小),分成指定线程数下载,或者指定每个线程承担下载任务的大小(再次我们仅以后者分析)

2,计算所需线程数

3,将获得的数据保存本地(使用RandomAccessFile流存储)

【代码】

package com.wsf.demo;

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

public class ImageDownload {

    public final static String sate = "http://www.baidu.com/img/bd_logo1.png";//本题所下载的文件是一个百度图标

    public static void main(String[] args) {
        try {
            //创建一个URL对象
            URL url = new URL(sate);
            //建立一个链接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            //制定相应方式
            conn.setRequestMethod("GET");
            //进行连接
            conn.connect();
            //获得响应码
            int code = conn.getResponseCode();
            //获得文件名字
            int position = sate.lastIndexOf("/");
            String fileName = sate.substring(position+1);
            System.out.println("服务器响应码:"+code);
            //如果响应码是200 则链接下载。。。
            if(code == HttpURLConnection.HTTP_OK){
                //获得文件长度
                int contentLength = conn.getContentLength();
                System.out.println("文件总长度:"+contentLength);
                //设定想要启动下载线程,用于把文件分成多少分进行下载
                RandomAccessFile raf = new RandomAccessFile(new File(fileName), "rwd");
                raf.setLength(contentLength);
                raf.close();
                
                //假定每个线程负责下载的长度为1k
                int blockSize = 1024*2;
                //如果能除尽指定线程数  否则线程数+1
                int size = contentLength%blockSize==0 ? contentLength/blockSize : (contentLength/blockSize)+1;
                
                for(int i = 0;i<size;i++){
                    if(i==(size-1)){
                        new DownLoadThread(i, (contentLength-(blockSize*i)), fileName,contentLength).start();
                        System.out.println("启动了第:"+i+"  线程---------------------"+(contentLength-(blockSize*i)));
                        return;
                    }
                    new DownLoadThread(i, blockSize, fileName,(i+1)*blockSize).start();
                    System.out.println("启动了第:"+i+"  线程---------------------"+blockSize);
                }
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
class DownLoadThread extends Thread{
    private int fileCount;
    private int blockSize;
    private String fileName;
    private int TotalLength;
    
    public DownLoadThread(int fileCount,int blockSize,String fileName,int TotalLength){
        this.fileCount = fileCount;
        this.blockSize = blockSize;
        this.fileName = fileName;
        this.TotalLength= TotalLength;
        
    }
    @Override
    public void run() {
            try {
                URL url = new URL(ImageDownload.sate);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setRequestProperty("Range", "bytes="+(TotalLength-blockSize)+"-"+(TotalLength));
                conn.connect();
                System.out.println(fileCount+"开始:"+(TotalLength-blockSize)+",结束:"+TotalLength);

               //多线程同时下载文件,因此要使用随机访问文件流,即同时写入读取,seek(int index)制定存放的位置
                RandomAccessFile raf = new RandomAccessFile(new File(fileName), "rwd");
                raf.seek(TotalLength-blockSize);
                int code = conn.getResponseCode();
                System.out.println(fileCount+">>>Code>>>"+code);
                if(code == HttpURLConnection.HTTP_OK || code == 206){
                    BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
                    int len = 0;                 
                    byte[]buf = new byte[1024];
                    while((len = bis.read(buf,0,buf.length))!=-1){
                        raf.write(buf, 0, len);
                        System.out.println(fileCount+"下载长度:"+len);
                    }
                    //回收资源
                    raf.close();
                    System.out.println("第"+fileCount+"段下载完毕!!!");
                    return;
                }
                System.out.println("第"+fileCount+"段下载失败!!!");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
    }
}

### 回答1: setRequestProperty() 方法是 java.net.URLConnection 类的一个方法,用于设置请求属性。使用这个方法可以设置请求头,例如设置内容类型、授权等。该方法的签名为: ``` public void setRequestProperty(String key, String value) ``` 其中,key 为请求头的名称,value 为请求头的值。 例如: ``` URL url = new URL("http://www.example.com"); URLConnection conn = url.openConnection(); conn.setRequestProperty("Accept-Language", "zh-cn"); ``` 上面的代码用于设置请求头中 "Accept-Language" 的值为 "zh-cn"。 ### 回答2: setRequestProperty方法是用于设置HTTP请求属性的。它是Java标准库中URLConnection类的一个方法,用于在发送HTTP请求时设置请求头信息。 该方法接受两个参数,第一个参数是属性的键,表示要设置的请求头字段的名称;第二个参数是属性的值,表示要设置的请求头字段的值。 通过setRequestProperty方法,我们可以在HTTP请求头中设置各种属性,例如: 1. 设置请求的Content-Type:通过setRequestProperty("Content-Type", "application/json"),可以将请求的Content-Type设置为"application/json"。这样,在发送POST请求时,可以将请求的主体数据格式设置为JSON。 2. 设置请求的授权信息:通过setRequestProperty("Authorization", "Bearer 123456"),可以将请求的授权信息设置为"Bearer 123456"。这样,在发送需要身份验证的请求时,可以将身份验证信息设置为指定的值。 3. 设置请求的User-Agent:通过setRequestProperty("User-Agent", "Mozilla/5.0"),可以将请求的User-Agent设置为"Mozilla/5.0"。这样,在发送HTTP请求时,可以模拟指定的浏览器或客户端。 setRequestProperty方法可以被多次调用,以设置多个请求头属性。注意,这个方法必须在调用URLConnection的connect方法之前被调用,否则设置的属性将不会生效。 综上所述,setRequestProperty方法是用于设置HTTP请求头信息的方法,通过它,我们可以设置各种属性,以满足不同HTTP请求的需求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值