source: java/HTTPFileDownloader/src/net/oni2/httpfiledownloader/FileDownloader.java@ 891

Last change on this file since 891 was 852, checked in by alloc, 12 years ago

AEI2.08, AEIUpdater:

File size: 5.5 KB
Line 
1package net.oni2.httpfiledownloader;
2
3import java.io.BufferedInputStream;
4import java.io.File;
5import java.io.FileNotFoundException;
6import java.io.IOException;
7import java.io.RandomAccessFile;
8import java.net.URL;
9import java.net.URLConnection;
10import java.util.HashSet;
11
12import net.oni2.ProxySettings;
13
14/**
15 * @author Christian Illy
16 */
17public class FileDownloader implements Runnable {
18 /**
19 * @author Christian Illy
20 */
21 public enum EState {
22 /**
23 * Downloader initialized but not started
24 */
25 INIT,
26 /**
27 * Download running
28 */
29 RUNNING,
30 /**
31 * Download suspended
32 */
33 PAUSED,
34 /**
35 * Download interrupted
36 */
37 INTERRUPTED,
38 /**
39 * Download finished successfully
40 */
41 FINISHED,
42 /**
43 * Aborted because of an error
44 */
45 ERROR
46 };
47
48 private HashSet<FileDownloadListener> listeners = new HashSet<FileDownloadListener>();
49 private Thread t = null;
50 private URL url = null;
51 private File target = null;
52 private int fileLength = Integer.MAX_VALUE;
53 private int downloaded = 0;
54
55 private EState state = EState.INIT;
56
57 /**
58 * @param url
59 * URL of file to download
60 * @param target
61 * Path of target file to save to
62 * @throws IOException
63 * If url could not be opened
64 */
65 public FileDownloader(String url, File target) throws IOException {
66 this.url = new URL(url);
67 this.target = target;
68 }
69
70 /**
71 * @param listener
72 * Listener to add
73 */
74 public void addListener(FileDownloadListener listener) {
75 listeners.add(listener);
76 }
77
78 /**
79 * @param listener
80 * Listener to remove
81 */
82 public void removeListener(FileDownloadListener listener) {
83 listeners.remove(listener);
84 }
85
86 /**
87 * Start the download process
88 */
89 public synchronized void start() {
90 if (t == null) {
91 state = EState.RUNNING;
92 t = new Thread(this);
93 t.start();
94 }
95 }
96
97 /**
98 * @param suspend
99 * Suspend or resume
100 */
101 public synchronized void suspend(boolean suspend) {
102 if ((state == EState.RUNNING) || (state == EState.PAUSED)) {
103 if (suspend)
104 state = EState.PAUSED;
105 else
106 state = EState.RUNNING;
107 updateStatus(downloaded, fileLength);
108 }
109 }
110
111 /**
112 * Stop (abort) download
113 */
114 public synchronized void stop() {
115 if (state != EState.FINISHED) {
116 state = EState.INTERRUPTED;
117 if (t != null) {
118 try {
119 t.join();
120 } catch (InterruptedException e) {
121 e.printStackTrace();
122 }
123 t = null;
124 }
125 updateStatus(0, 1);
126 if (target.exists())
127 target.delete();
128 }
129 }
130
131 /**
132 * @return current state
133 */
134 public EState getState() {
135 return state;
136 }
137
138 private synchronized void updateStatus(int current, int total) {
139 downloaded = current;
140 for (FileDownloadListener l : listeners) {
141 l.statusUpdate(this, state, current, total);
142 }
143 }
144
145 @Override
146 public void run() {
147 int downloaded = 0;
148 String strLastModified = null;
149 String strEtag = null;
150 RandomAccessFile outFile = null;
151
152 try {
153 outFile = new RandomAccessFile(target, "rw");
154 } catch (FileNotFoundException e1) {
155 e1.printStackTrace();
156 state = EState.ERROR;
157 updateStatus(downloaded, fileLength);
158 return;
159 }
160
161 try {
162 while (downloaded < fileLength) {
163 switch (state) {
164 case ERROR:
165 updateStatus(downloaded, fileLength);
166 return;
167 case PAUSED:
168 try {
169 Thread.sleep(100);
170 } catch (InterruptedException e) {
171 e.printStackTrace();
172 }
173 break;
174 case INTERRUPTED:
175 return;
176 case RUNNING:
177 BufferedInputStream input = null;
178 try {
179 URLConnection connection = url
180 .openConnection(ProxySettings.getInstance()
181 .getProxy());
182 connection.setRequestProperty("Cache-Control",
183 "no-cache");
184 if (downloaded == 0) {
185 connection.connect();
186 strLastModified = connection
187 .getHeaderField("Last-Modified");
188 strEtag = connection.getHeaderField("ETag");
189 fileLength = connection.getContentLength();
190 } else {
191 connection.setRequestProperty("Range", "bytes="
192 + downloaded + "-");
193 if (strEtag != null)
194 connection.setRequestProperty("If-Range",
195 strEtag);
196 else
197 connection.setRequestProperty("If-Range",
198 strLastModified);
199 connection.connect();
200 }
201
202 // Setup streams and buffers.
203 input = new BufferedInputStream(
204 connection.getInputStream(), 8192);
205 if (downloaded > 0)
206 outFile.seek(downloaded);
207 byte data[] = new byte[1024];
208
209 // Download file.
210 int dataRead = 0;
211 int i = 0;
212 while (((dataRead = input.read(data, 0, 1024)) != -1)
213 && (state == EState.RUNNING)) {
214 outFile.write(data, 0, dataRead);
215 downloaded += dataRead;
216 if (downloaded >= fileLength)
217 break;
218
219 i++;
220 if ((i % 50) == 0)
221 updateStatus(downloaded, fileLength);
222 }
223 input.close();
224 } catch (IOException e) {
225 // TODO Auto-generated catch block
226 e.printStackTrace();
227 try {
228 if (input != null)
229 input.close();
230 } catch (IOException e2) {
231 e2.printStackTrace();
232 }
233 }
234 break;
235 default:
236 break;
237 }
238 }
239 } finally {
240 try {
241 // Close streams.
242 outFile.close();
243 } catch (IOException e) {
244 e.printStackTrace();
245 }
246 }
247
248 state = EState.FINISHED;
249 updateStatus(downloaded, fileLength);
250 }
251
252 /**
253 * @return the target
254 */
255 public File getTarget() {
256 return target;
257 }
258
259 /**
260 * @return the downloaded size
261 */
262 public int getDownloaded() {
263 return downloaded;
264 }
265
266}
Note: See TracBrowser for help on using the repository browser.