1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.example.android.systemupdatersample.util;
18 
19 import android.util.Log;
20 
21 import java.io.File;
22 import java.io.FileOutputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.OutputStream;
26 import java.net.URL;
27 import java.net.URLConnection;
28 
29 /**
30  * Downloads chunk of a file from given url using {@code offset} and {@code size},
31  * and saves to a given location.
32  *
33  * In a real-life application this helper class should download from HTTP Server,
34  * but in this sample app it will only download from a local file.
35  */
36 public final class FileDownloader {
37 
38     private String mUrl;
39     private long mOffset;
40     private long mSize;
41     private File mDestination;
42 
FileDownloader(String url, long offset, long size, File destination)43     public FileDownloader(String url, long offset, long size, File destination) {
44         this.mUrl = url;
45         this.mOffset = offset;
46         this.mSize = size;
47         this.mDestination = destination;
48     }
49 
50     /**
51      * Downloads the file with given offset and size.
52      * @throws IOException when can't download the file
53      */
download()54     public void download() throws IOException {
55         Log.d("FileDownloader", "downloading " + mDestination.getName()
56                 + " from " + mUrl
57                 + " to " + mDestination.getAbsolutePath());
58 
59         URL url = new URL(mUrl);
60         URLConnection connection = url.openConnection();
61         connection.connect();
62 
63         // download the file
64         try (InputStream input = connection.getInputStream()) {
65             try (OutputStream output = new FileOutputStream(mDestination)) {
66                 long skipped = input.skip(mOffset);
67                 if (skipped != mOffset) {
68                     throw new IOException("Can't download file "
69                             + mUrl
70                             + " with given offset "
71                             + mOffset);
72                 }
73                 byte[] data = new byte[4096];
74                 long total = 0;
75                 while (total < mSize) {
76                     int needToRead = (int) Math.min(4096, mSize - total);
77                     int count = input.read(data, 0, needToRead);
78                     if (count <= 0) {
79                         break;
80                     }
81                     output.write(data, 0, count);
82                     total += count;
83                 }
84                 if (total != mSize) {
85                     throw new IOException("Can't download file "
86                             + mUrl
87                             + " with given size "
88                             + mSize);
89                 }
90             }
91         }
92     }
93 
94 }
95