import java.io.*; import java.net.*; import java.util.*; class Download: Runnable { public enum class Status { DOWNLOADING, PAUSED, COMPLETE, CANCELLED, ERROR } public var size: Int public var downloaded: Int public var contentLength: Int public var status: Status private final val MAX_BUFFER_SIZE: Number = 1024 private var url: URL constructor (url: URL) { this.url = url size = -1 downloaded = 0 status = Status.DOWNLOADING contentLength = 1 } public fun start() { val thread = Thread(this) thread.start() } private fun getFilename(url: URL): String { val filename = url.getFile() return filename.substring(filename.lastIndexOf('/') + 1) } override fun run() { var stream: InputStream? = null var file: RandomAccessFile? = null try { // Open connection to URL. var connection = url.openConnection() as HttpURLConnection; // Specify what portion of file to download. connection.setRequestProperty("Range", "bytes=" + downloaded + "-"); // Connect to server. connection.connect(); // Make sure response code is in the 200 range. if (connection.responseCode / 100 != 2) { status = Status.ERROR } // Check for valid content length. contentLength = connection.getContentLength(); if (contentLength < 1) { status = Status.ERROR } /* Set the size for this download if it hasn't been already set. */ if (size == -1) { size = contentLength; } // Open file and seek to the end of it. file = RandomAccessFile(getFilename(url), "rw"); file.seek(downloaded.toLong()); stream = connection.getInputStream(); while (status == Status.DOWNLOADING) { /* Size buffer according to how much of the file is left to download. */ val buffer: ByteArray; if (size - downloaded > MAX_BUFFER_SIZE as Int) { buffer = ByteArray(MAX_BUFFER_SIZE) } else { buffer = ByteArray(size - downloaded); } // Read from server into buffer. val read = stream.read(buffer); if (read == -1) break; // Write buffer to file. file.write(buffer, 0, read); downloaded += read; } /* Change status to complete if this point was reached because downloading has finished. */ if (status == Status.DOWNLOADING) { status = Status.COMPLETE; } } catch (e: Exception) { status = Status.ERROR } finally { // Close file. if (file != null) { try { file.close(); } catch (e: Exception) {} } // Close connection to server. if (stream != null) { try { stream.close(); } catch (e: Exception) {} } } } }