The HTTP protocol helps us handle this task with much ease by making use of ETags
The class below is ready to use. Copy and paste the code into your Android project.
import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.io.Writer; import java.net.HttpURLConnection; import java.net.URL; public class FileDownloadHelper { private final int BUFFER_SIZE=1024*32; private final String IFNONEMATCH_HEADER_FIELD = "If-None-Match"; private final String ETAG_HEADER_FIELD = "ETag"; public void downloadToFile(String sourceUrl, String destFile) throws IOException{ URL url = new URL(sourceUrl); downloadToFileHTTP(url, destFile); } private void downloadToFileHTTP(URL url, String destFile) throws IOException{ HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // accept compressed content connection.setRequestProperty("Accept-Encoding", "gzip, deflate"); try{ writeHTTPDataToFileStream(connection, destFile); }finally{ connection.disconnect(); } } private void writeHTTPDataToFileStream(HttpURLConnection connection, String destFile) throws IOException{ String etagFileName = buildEtagFileName(destFile); String etag = readTextFile(etagFileName); addETagHeader(connection, etag); int responseCode = connection.getResponseCode(); if(responseCode == HttpURLConnection.HTTP_OK){ FileOutputStream destFileStream = new FileOutputStream(destFile); try{ InputStream connectionStream = new BufferedInputStream(connection.getInputStream()); try{ int bytesRead; byte[] readBuffer = new byte[BUFFER_SIZE]; while((bytesRead = connectionStream.read(readBuffer)) > 0){ destFileStream.write(readBuffer, 0, bytesRead); } }finally{ connectionStream.close(); } }finally{ destFileStream.close(); } saveETagHeader(connection, destFile); } } private void saveETagHeader(HttpURLConnection connection, String destFile) throws IOException { String etag = connection.getHeaderField(ETAG_HEADER_FIELD); if(etag != null && etag.length()>2){ String etagFile = buildEtagFileName(destFile); saveToTextFile(etagFile, etag); } } private void addETagHeader(HttpURLConnection connection, String etag){ // greater than 2 because it must at least include the double quotes if(etag!=null && etag.length()>2){ connection.addRequestProperty(IFNONEMATCH_HEADER_FIELD, etag); } } private String readTextFile(String fileName) throws IOException{ File f = new File(fileName); if(f.exists() && f.length()>0){ Reader reader = new BufferedReader(new FileReader(fileName)); try { char[] buffer = new char[1024 * 8]; StringBuilder resultBuilder = new StringBuilder(); int br; while ((br = reader.read(buffer)) > 0) { resultBuilder.append(buffer, 0, br); } return resultBuilder.toString(); } finally { reader.close(); } } return ""; } private void saveToTextFile(String fileName, String contents) throws IOException { Writer writer = new BufferedWriter(new FileWriter(fileName)); try { writer.write(contents); } finally { writer.close(); } } private String buildEtagFileName(String fileName){ return fileName + ".etag"; } }
Note that a .etag file will be created in the same directory as the downloaded file and reused in future downloads.
Just call FileDownloadHelper.downloadToFile like this:
FileDownloadHelper client = new FileDownloadHelper(); // assuming you are in the activity context String fileName = getFilesDir().getAbsolutePath()+"/devhelpers.html"; // this will download an html page but you can pass any url to the method String webPageUrl = "http://devhelpers.blogspot.ca/"; client.downloadToFile(webPageUrl, fileName);
No comments:
Post a Comment