示例#1
0
  /**
   * Given a file and a source this will start a worker-less file downloading.
   *
   * @param nF
   * @param bestSource
   */
  private void startFileDownloading(DownloadFile nF, DownloadSource bestSource) {
    // first ensure that the file is not already complete on disk:
    if (downloadFileCompleteOnDisk(nF)) {
      Logger.warn("Complete download: " + nF + " was in the queue. Issueing completion.");
      nF.downloadComplete(); // issue completion
      wereCompleteItemsInQueue = true;
      return;
    }

    // Create a new info container for the file (if it has never been started before, or if for some
    // reason there are no chunks in it (corrupt for some reason? broken code in the past probably))
    if (nF.active == null) {
      if (nF.getSize() == 0) {
        // zero byte files do not need downloading. (and indeed they will fail to dispatch correctly
        // as they will never have any incomplete chunks)
        try {
          nF.getFile().createNewFile();
          nF.downloadComplete();
          wereCompleteItemsInQueue = true;
          return;
        } catch (IOException e) {
          Logger.severe(
              "Empty file: " + nF.getFile().getPath() + " couldn't be created on disk: " + e);
        }
      }
      nF.active = new DownloadInfo(nF);
    } else {
      if (nF.active.isComplete()) {
        Logger.warn("Complete download: " + nF + " was in the queue. Issueing completion.");
        nF.downloadComplete();
        wereCompleteItemsInQueue = true;
        return;
      } else if (nF.active.chunks.size() == 0) {
        Logger.warn(
            "Active download '"
                + nF
                + "' in queue with no chunks. Restarting download from the beginning.");
        nF.active = new DownloadInfo(nF);
      }
    }

    try {
      // Create the new worker:
      DownloadWorker w = DownloadWorker.getDownloadWorker(this, nF.active);
      nF.active.worker = w;
      workers.add(w);

      // Start one of the download chunks present in the info:
      for (DownloadChunk c : w.getIncompleteInactiveChunks()) {
        w.downloadChunk(c, bestSource, downloadThreadPool);
        break;
      }
    } catch (IOException e) {
      Logger.severe("Unable to dispatch a download: " + e);
      Logger.log(e);
    }
  }
示例#2
0
 /**
  * Finds a file that is not being serviced by a download worker and starts to download it.
  *
  * @return true iff there was a file in the queue to consider, false otherwise.
  */
 private synchronized boolean dispatchFile() {
   // 1) establish the active directory:
   DownloadFile nF = controller.q.getInactiveDownloadFile();
   if (nF != null) {
     // Logger.log("attempting to dispatch: "+nF);
     // start it downloading...
     // 1) find a source for the download:
     Map<String, DownloadSource> sources =
         controller.ssvr.getIndexNodeCommunicator().getSourcesForFile(nF.hash);
     if (sources.isEmpty()) {
       nF.notifyNoSources();
     } else {
       startFileDownloading(nF, controller.peerstats.getBestSource(sources));
     }
     return true;
   } else {
     // Logger.log("Nothing to dispatch.");
     return false;
   }
 }
示例#3
0
  /**
   * Checks if the downloadFile specified has been completed already. This returns true iff: ) file
   * exists ) is expected size ) hashes to the same fs2 hash.
   *
   * @param f
   * @return
   */
  private boolean downloadFileCompleteOnDisk(DownloadFile f) {
    try {
      File onDisk = f.getFile();
      if (!onDisk.isFile()) return false;
      if (onDisk.length() != f.size) return false;
      if (!ThrottledFileDigester.fs2DigestFile(onDisk, null).equals(f.hash)) return false;
    } catch (Exception e) {
      Logger.warn("Couldn't test for file completion on disk: " + e);
      Logger.log(e);
      return false;
    }

    return true; // it's already complete!
  }