Reputation: 121
I have a java application in which I download files using HttpURLConnection. I set 15 Seconds in connect timeout and 1 hour in read timeout properties. As per my understanding, if file on server is big enough to take more than 1 hour to download, it will fail with timeout exception. Works fine. The problem is, when I pull the Internet cable out from the client machine while download is in progress(reading buffer from InputStream), the download process does not terminates immediately, it takes 1 hour (read timeout) to break the download. Is there any way I can terminate the download process? Following is the source code:
public class HttpDownloadUtility {
private static final int BUFFER_SIZE = 4096;
public static void downloadFile(String fileURL, String saveDir)
throws IOException {
URL url = new URL(fileURL);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
httpConn.setConnectTimeout(15*1000);
httpConn.setReadTimeout(60*60*1000);
int responseCode = httpConn.getResponseCode();
// always check HTTP response code first
if (responseCode == HttpURLConnection.HTTP_OK) {
String fileName = "";
String disposition = httpConn.getHeaderField("Content-Disposition");
String contentType = httpConn.getContentType();
int contentLength = httpConn.getContentLength();
if (disposition != null) {
// extracts file name from header field
int index = disposition.indexOf("filename=");
if (index > 0) {
fileName = disposition.substring(index + 10,
disposition.length() - 1);
}
} else {
// extracts file name from URL
fileName = fileURL.substring(fileURL.lastIndexOf("/") + 1,
fileURL.length());
}
System.out.println("Content-Type = " + contentType);
System.out.println("Content-Disposition = " + disposition);
System.out.println("Content-Length = " + contentLength);
System.out.println("fileName = " + fileName);
// opens input stream from the HTTP connection
InputStream inputStream = httpConn.getInputStream();
String saveFilePath = saveDir + File.separator + fileName;
// opens an output stream to save into file
FileOutputStream outputStream = new FileOutputStream(saveFilePath);
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = inputStream.read(buffer)) != -1) { //This is where the download gets stuck on some connection issues
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();
System.out.println("File downloaded");
} else {
System.out.println("No file to download. Server replied HTTP code: " + responseCode);
}
httpConn.disconnect();
}
}
Upvotes: 4
Views: 4799
Reputation: 310913
As per my understanding, if file on server is big enough to take more than 1 hour to download, it will fail with timeout exception.
No. If the server fails to respond to any single read request for over an hour, it will fail. The timeout starts when you call read()
, and ends when a response to that read is received or the timeout period expires. Then it starts again next read. Total time has nothing to do with it. You've misunderstood completely.
Works fine.
Works fine but not as you described.
The problem is, when I pull the Internet cable out from the client machine while download is in progress(reading buffer from InputStream), the download process does not terminates immediately, it takes 1 hour (read timeout) to break the download.
That's exactly what it's supposed to do, as described above.
Is there any way I can terminate the download process?
Set a shorter timeout. Set it long enough so the server should respond within that interval, and short enough hat a cable pull doesn't take too long to time out. An hour is too long. Try a few minutes.
Upvotes: 2