Skip to content

Instantly share code, notes, and snippets.

@qrtt1
Last active December 17, 2015 13:39
Show Gist options
  • Save qrtt1/5618522 to your computer and use it in GitHub Desktop.
Save qrtt1/5618522 to your computer and use it in GitHub Desktop.
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