简体   繁体   English

如何从android中的URL下载文件的一部分?

[英]How to download a part of a file from URL in android?

I am trying to download a part of file given the download URL using setRequestProperty("Range","bytes=" + startbytes + "-" + endbytes); 我试图使用setRequestProperty(“Range”,“bytes =”+ startbytes +“ - ”+ endbytes)下载给定下载URL的文件的一部分; The following code snippet shows what I am trying to do. 以下代码段显示了我要执行的操作。

protected String doInBackground(String... aurl) {
    int count;
    Log.d(TAG,"Entered");
    try {

        URL url = new URL(aurl[0]);
        HttpURLConnection connection =(HttpURLConnection) url.openConnection();

        int lengthOfFile = connection.getContentLength();

        Log.d(TAG,"Length of file: "+ lengthOfFile);

        connection.setRequestProperty("Range", "bytes=" + 0 + "-" + 1000);

The problem is that, an exception is being raised, which says "Cannot set request property after connection is made". 问题在于,引发了一个异常,即“在建立连接后无法设置请求属性”。 Please help me resolve this issue. 请帮我解决这个问题。

Option 1 选项1

If you do not need to know the content length: 如果您不需要知道内容长度:

[Beware, do not call the connection.getContentLength() . [注意,不要调用connection.getContentLength() If you call that, you will get the exception. 如果你打电话,你会得到例外。 If you need to call it, then check the second option] 如果你需要打电话,那么检查第二个选项]

URL url = new URL(aurl[0]);
HttpURLConnection connection =(HttpURLConnection) url.openConnection();
connection.setRequestProperty("Range", "bytes=" + 0 + "-" + 1000);
//Note that, response code will be 206 (Partial Content) instead of usual 200 (OK)
if(connection.getResponseCode() == HttpURLConnection.HTTP_PARTIAL){
    //Your code here to read response data
}

Option 2 选项2

If you need to know the content length: 如果您需要知道内容长度:

URL url = new URL(aurl[0]);
//First make a HEAD call to get the content length  
HttpURLConnection connection =(HttpURLConnection) url.openConnection();
connection.setRequestMethod("HEAD");
if(connection.getResponseCode() == HttpURLConnection.HTTP_OK){
    int lengthOfFile = connection.getContentLength();
    Log.d("ERF","Length of file: "+ lengthOfFile);
    connection.disconnect();

    //Now that we know the content lenght, make the GET call
    connection =(HttpURLConnection) url.openConnection();
    connection.setRequestMethod("GET");
    connection.setRequestProperty("Range", "bytes=" + 0 + "-" + 1000);
    //Note that, response code will be 206 (Partial Content) instead of usual 200 (OK)
    if(connection.getResponseCode() == HttpURLConnection.HTTP_PARTIAL){
        //Your code here to read response data

    }
}

Assuming you're using HTTP for the download, you'll want to use the HEAD http verb and RANGE http header. 假设您使用HTTP进行下载,您将需要使用HEAD http动词和RANGE http标头。

HEAD will give you the filesize (if available), and then RANGE lets you download a byte range. HEAD将为您提供文件大小(如果可用),然后RANGE允许您下载字节范围。

Once you have the filesize, divide it into roughly equal sized chunks and spawn download thread for each chunk. 获得文件大小后,将其划分为大致相等大小的块,并为每个块生成下载线程。 Once all are done, write the file chunks in the correct order. 完成所有操作后,按正确的顺序写入文件块。

If you don't know how to use the RANGE header, here's another SO answer that explains how: https://stackoverflow.com/a/6323043/1355166 如果你不知道如何使用RANGE标题,这里有另一个SO答案解释如何: https//stackoverflow.com/a/6323043/1355166

[EDIT] [编辑]

To make file into chunks use this, and start the downloading process, 要将文件分成块,请使用此命令,然后开始下载过程,

private void getBytesFromFile(File file) throws IOException {
    FileInputStream is = new FileInputStream(file); //videorecorder stores video to file

    java.nio.channels.FileChannel fc = is.getChannel();
    java.nio.ByteBuffer bb = java.nio.ByteBuffer.allocate(10000);

    int chunkCount = 0;

    byte[] bytes;

    while(fc.read(bb) >= 0){
        bb.flip();
        //save the part of the file into a chunk
        bytes = bb.array();
        storeByteArrayToFile(bytes, mRecordingFile + "." + chunkCount);//mRecordingFile is the (String)path to file
        chunkCount++;
        bb.clear();
    }
}

private void storeByteArrayToFile(byte[] bytesToSave, String path) throws IOException {
    FileOutputStream fOut = new FileOutputStream(path);
    try {
        fOut.write(bytesToSave);
    }
    catch (Exception ex) {
        Log.e("ERROR", ex.getMessage());
    }
    finally {
        fOut.close();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM