0

我正在开发一个黑莓应用程序,但我在恢复下载时遇到了问题。如果下载没有中断,该代码运行良好,但如果中断并重新开始下载,则媒体文件会失真。

为了允许恢复下载,我从服务器请求文件块并保存最后一个成功下载/写入的块。因此,如果我要重新开始下载,我会检查最后下载和写入的块,增加它并使用它来确定从服务器请求的范围。我的代码如下所示..:

public final class Downloader extends Thread {

  private String remoteName;
  private String localName;
  private String parentDir;
  private String dirName;
  public String fileName;

  private int chunkSize = 512000;
  public boolean completed = false;
  public boolean failed = false;

  public CacheObject cacheObject = null

  public Downloader(String remoteName, String localName, String musicTitle, String parentDir, String dirName) {

      this.remoteName = remoteName; 
      this.parentDir = parentDir;
      this.dirName = dirName;
      this.localName = localName;
      this.secureDownload = false;
      this.musicTitle = musicTitle;

      this.cacheObject = CachedObject.getInstance().findCachedObject(musicTitle);

      if (this.cacheObject == null) // create new object
          this.cacheObject = new CachedObject(musicTitle, remoteName);

      this.thisObj = this;
    }

    public void run() {
        downloadFile(localName);
    }

    public void downloadFile(String fileName) {
        try {
            int chunkIndex = 0; int totalSize = 0;

            String tempFileName = "file:///" + FileConnect.getInstance().FILE_ROOT+parentDir+ FileConnect.getInstance().FILE_SEPARATOR;

            if (!FileConnect.getInstance().fileExists(tempFileName))
                FileConnect.getInstance().createDirectory(parentDir);

            if (dirName != null) {
                tempFileName = "file:///" + FileConnect.getInstance().FILE_ROOT+ parentDir + "/" + dirName + FileConnect.getInstance().FILE_SEPARATOR;

                if (!FileConnect.getInstance().fileExists(tempFileName))
                   FileConnect.getInstance().createDirectory(parentDir + "/" + dirName);
            }

            fileName = tempFileName + fileName;
            this.fileName = fileName;


            file = (FileConnection) Connector.open(fileName, Connector.READ_WRITE);

            if (!file.exists()) {
               file.create();
            }

            if(cacheObject.file_path.length() < 1)
                cacheObject.file_path = fileName;

            file.setWritable(true);

            // Trying to check the file size.
            long fSize = (int)file.fileSize();

            // If it is greater than 1 byte, then we open an output stream at the end of the file
            if(fSize > 1){
                out = file.openOutputStream((fSize+1));
            }
            else{
              out = file.openOutputStream();
            }


            int rangeStart = 0; int rangeEnd = 0;


           // Want to know the total fileSize on server (used for updating the UI..
            HttpConnection conn2;
            conn2 = (HttpConnection) Util.getHttpConnection(remoteName);
            String totalFileSize = "" + conn2.getLength();
            conn2.close();

           //Number of chunks
           int numChunks = (int) Math.ceil( Integer.parseInt(totalFileSize) / chunkSize); 
           cacheObject.chunk_size = numChunks;


           // Set the total file size..
           content_length = Integer.parseInt(totalFileSize);
           fileSize = 0;
           String url = remoteName + HttpRequestDispatcher.getConnectionString();


           if(cacheObject.last_successfully_downloaded_chunk > -1){
              //This is a resume..
              if( (cacheObject.last_successfully_downloaded_chunk + 1) < numChunks ){
                  chunkIndex = cacheObject.last_successfully_downloaded_chunk + 1;

                  fileSize = cacheObject.curr_download_size;
              }             
           }    



          while (file != null) {
              try{
                  conn = (HttpConnection)Connector.open(url);

                  if(chunkIndex < (numChunks-2)){
                      rangeStart = chunkIndex * chunkSize; rangeEnd = rangeStart + chunkSize - 1;
                  }
                  else{
                      rangeStart = chunkIndex * chunkSize;
                      int remainingBytes = Integer.parseInt(totalFileSize) - rangeStart; rangeEnd = rangeStart + (remainingBytes - 1);
                  }

                  conn.setRequestProperty("User-Agent", "Profile/MIDP-2.0 Configuration/CLDC-1.0");
                  conn.setRequestProperty("Connection", "keep-alive");


                  conn.setRequestProperty("Range", "bytes=" + rangeStart + "-" + rangeEnd);
                  responseCode = conn.getResponseCode();                

                  if (responseCode != 200 && responseCode != 206) {     
                     out.flush(); out.close(); file.close(); in.close(); conn.close(); 
                     in = null; conn = null; file = null; out = null; 
                     Thread.yield(); break;
                  }
                  else{

                     in = conn.openInputStream(); int length = -1;
                     byte[] readBlock = new byte[256];

                     while ((length = in.read(readBlock)) != -1) {
                         out.write(readBlock, 0, length);
                         fileSize += length;
                         cacheObject.curr_download_size = fileSize;
                     }

                     totalSize += fileSize;


                     in.close(); conn.close(); in = null; conn = null;

                      // Update after the byte read..
                      cacheMusicbox.last_successfully_downloaded_chunk = chunkIndex;
                      CachedObject.getInstance().saveCachedObject( cacheObject);

                      System.out.println("Last successful chunk downloaded: " + cacheObject.last_successfully_downloaded_chunk);

                      chunkIndex++;
                      if(chunkIndex == numChunks){
                          out.flush(); out.close();  file.close(); break;
                      }

                      Thread.yield();
                  }
              }
              // Network error related
              catch(Exception e){
                 System.out.println("Download failed. Some kind of error - " + e.getMessage());
                 System.out.println("fileSize b4 closed: ." + file.fileSize());             
                 System.out.println("Last successful chunk downloaded: " + cacheMusicbox.last_successfully_downloaded_chunk);

                  if (out != null) {
                      out.flush(); out.close();
                      System.out.println("We just closed the outputStream");
                      System.out.println("fileSize when closed: ." + file.fileSize());
                  }
                  if (file != null && file.exists()) {
                      if (file.isOpen()) {          
                          file.close();
                      }
                  }

                  in = null; conn = null; file = null; out = null;
                  failed = true;
                  System.out.println("Ensuring this block is called " + cacheObject.last_successfully_downloaded_chunk);

                  break;
              }
          }


          System.out.println("Full file downloaded: " + totalSize + " Bytes");
          System.out.println("Wrote file to local storage");
          Thread.sleep(3000);

          if(!failed)
              completed = true;

       } 
       // any other error...
       catch (Exception e) {
          System.out.println(e.getMessage());

          try{
              out.flush(); out.close(); file.close();           
              in = null; conn = null;   file = null; out = null;
          }
          catch(Exception ee){
              System.out.println("While closing catch that belongs to the top guy: " + ee.getMessage());
          }
          failed = true;
        }
    }

}
4

1 回答 1

0

所以我终于得到了这个工作。这就是我所做的,希望它能帮助某人并使他们免于头痛..:)

如果我想恢复下载,我会遵循以下方法:

  1. 我检查了文件大小(根据 RIM,fileSize 对应于文件中包含的字节)并在文件末尾打开一个 outputStream。
  2. 我从那端开始从服务器请求文件.. 例如,当链接关闭时文件大小为 500kb,我将开始在 500-(500+chunkSize) 范围内请求,直到我到达文件末尾。
  3. 并且该过程继续如问题中所述
于 2014-10-08T17:09:17.383 回答