Last active
December 17, 2015 13:39
-
-
Save qrtt1/5618522 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.demo; | |
import java.io.ByteArrayOutputStream; | |
import java.io.FileOutputStream; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.OutputStream; | |
import java.net.HttpURLConnection; | |
import java.net.URL; | |
import java.util.logging.Logger; | |
public class HttpPartialDownloader { | |
final int blockSize = 1024 * 1024; | |
Logger logger = Logger.getLogger(HttpPartialDownloader.class.getName()); | |
URL url; | |
HttpURLConnection connection; | |
int length; | |
int numberOfchunk; | |
public HttpPartialDownloader(String u) throws IOException { | |
this.url = new URL(u); | |
initialize(); | |
} | |
protected void initialize() throws IOException { | |
connection = (HttpURLConnection) url.openConnection(); | |
length = connection.getContentLength(); | |
numberOfchunk = (int) (1F + (length / (blockSize + 0F))); | |
logger.info("content-length: " + length + ", num-of-chunks: " + numberOfchunk); | |
} | |
public byte[] get(int index) throws IOException { | |
int start = getOffset(index); | |
int end = getOffset(index + 1) - 1; | |
if (start == end) { | |
return new byte[0]; | |
} | |
if (index + 1 == numberOfchunk) { | |
end = length; | |
} | |
renewUrlConnection(); | |
String rangeRequest = String.format("bytes=%d-%d", start, end); | |
connection.setRequestProperty("Range", rangeRequest); | |
logger.info("req: " + rangeRequest); | |
ByteArrayOutputStream out = new ByteArrayOutputStream(); | |
int sum = doDownload(out); | |
/* we don't check the block-size for the last chunk */ | |
if (index + 1 == numberOfchunk) { | |
return out.toByteArray(); | |
} | |
if (sum == blockSize) { | |
return out.toByteArray(); | |
} | |
return new byte[0]; | |
} | |
protected void renewUrlConnection() throws IOException { | |
connection.disconnect(); | |
connection = (HttpURLConnection) url.openConnection(); | |
} | |
protected int doDownload(OutputStream out) throws IOException { | |
byte[] buf = new byte[16 * 1024]; | |
int sumOfReadBytes = 0; | |
int count; | |
InputStream in = connection.getInputStream(); | |
try { | |
while (true) { | |
count = in.read(buf); | |
if (count == -1) { | |
break; | |
} | |
sumOfReadBytes += count; | |
out.write(buf, 0, count); | |
} | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} finally { | |
in.close(); | |
} | |
return sumOfReadBytes; | |
} | |
protected int getOffset(int index) { | |
/* | |
* 利用等差數列公式 An = A1 + (n-1) * d | |
*/ | |
int n = index + 1; /* 公式第 1 項是 1 開始,不是 0 開始 */ | |
int nValue = 0 + (n - 1) * blockSize; | |
if (nValue > length) { | |
return length; | |
} | |
return nValue; | |
} | |
public int getNumberOfChunk() { | |
return numberOfchunk; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment