private def downloadNative()

in ideaSupport/src/main/scala/org/jetbrains/sbtidea/download/FileDownloader.scala [185:262]


  private def downloadNative(
    url: URL,
    reuseExistingPartFile: Boolean,
    isFirstAttempt: Boolean
  )(progressCallback: ProgressCallback): DownloadedPath = {
    val connection = url.openConnection()
    connection.setConnectTimeout(SocketConnectionTimeoutMs)
    connection.setReadTimeout(SocketReadTimeoutMs)

    val remoteMetaData = fetchRemoteMetaData(url)
    val fileNameWithoutPartSuffix =
      if (remoteMetaData.fileName.nonEmpty)
        remoteMetaData.fileName
      else
        Math.abs(url.hashCode()).toString

    val to = downloadDirectory.resolve(fileNameWithoutPartSuffix)
    val toLength = if (to.toFile.exists()) Files.size(to) else -1

    //The file can be present if this VM option was set in previous project import run:
    // `-Dsbt.idea.plugin.keep.downloaded.files`
    //
    //NOTE: file can be present but can have a different size for some idea versions
    //E.g. ideaIU-231.7515-EAP-CANDIDATE-SNAPSHOT can in reality represent different 231.7517.* versions
    //Because when new EAP-CANDIDATE is uploaded, the previous one is overridden
    if (remoteMetaData.length == toLength) {
      log.warn(s"File already downloaded: $to")
      return DownloadedPath.ZipPath(to)
    }

    val toPart = toFilePartPath(downloadDirectory.resolve(fileNameWithoutPartSuffix))
    val tpPartLength = if (toPart.toFile.exists()) Files.size(toPart) else -1

    if (remoteMetaData.length == tpPartLength) {
      log.warn(s"Part file already downloaded: recovering interrupted install...")
      return DownloadedPath.PartPath(toPart)
    }

    val resumePartFileDownload = toPart.toFile.exists() &&
      isResumeSupported(url) &&
      // reuseExistingPartFile is effective only during the first download try
      (reuseExistingPartFile || !isFirstAttempt)
    if (resumePartFileDownload) {
      connection.setRequestProperty("Range", s"bytes=$tpPartLength-")
      log.info(s"Resuming download of $url to $toPart")
    } else {
      Files.deleteIfExists(toPart)
      log.info(s"Starting download $url to $toPart")
    }

    var inChannel: ReadableByteChannel = null
    var outStream: FileOutputStream    = null
    try {
      val blockSize = 1 << 24 // 16M
      var transferred = -1L
      inChannel = Channels.newChannel(connection.getInputStream)
      outStream = new FileOutputStream(toPart.toFile, toPart.toFile.exists())
      val expectedFileSize = remoteMetaData.length
      val rbc = new RBCWrapper(inChannel, expectedFileSize, tpPartLength, progressCallback, toPart)
      val fileChannel = outStream.getChannel
      var position = fileChannel.position()

      while (transferred != 0) {
        transferred = fileChannel.transferFrom(rbc, position, blockSize)
        position += transferred
      }

      if (expectedFileSize > 0 && Files.size(toPart) != expectedFileSize) {
        throw new DownloadException(s"Incorrect downloaded file size: expected $expectedFileSize, got ${Files.size(toPart)}")
      } else {
        rbc.ensureFinalLogProgressCall()
      }
      DownloadedPath.PartPath(toPart)
    } finally {
      try { if (inChannel != null) inChannel.close() } catch { case e: Exception => log.error(s"Failed to close input channel: $e") }
      try { if (outStream != null) outStream.close() } catch { case e: Exception => log.error(s"Failed to close output stream: $e") }
    }
  }