2011-09-13 59 views
0

我正在下載分離線程中的圖像集並將它們保存到SD卡。問題是,當我運行兩個或更多下載線程時,保存的圖像已損壞。如果只有一個線程正在運行,則圖像就可以。我從相同的網域下載了不同的網址,例如www.test.com/set1/img1.jpg,www.test.com/set2/img1.jpg等同時下載導致損壞的文件

我通過設置的名稱將它們保存到不同的文件夾。我注意到大多數較大的圖像已損壞(超過500 KB),較小的通常可以,但並非總是如此。

你有什麼線索爲什麼在多線程運行時文件被損壞?

下面是我使用的代碼的一部分:

protected class DownloadTask extends DownloadRunnable { 

    @Override 
    public void run() { 
     InputStream is = null; 
     OutputStream os = null; 
     File bitmapFile = null; 
     /** some more declarations and preparations are here */ 

     for (int pg=getDownloadedPages(); pg < numPages; ++pg) { 

      for (char ch='a'; ch <= 'e'; ++ch) { 
       /* check for pause */ 
       synchronized (pauseLock) { 
        while (paused && !aborted) { 
         try { 
          pauseLock.wait(); 
         } catch (InterruptedException e) { 
         }        
        } 
       } 
       fileName = "page-" + df.format(pg) + "-" + ch;       
       url = MainApp.getRestrictedUrl(MainApp.tstcode, urlFile + fileName+ ".jpg");        
       is = new BufferedInputStream(new URL(url).openStream()); 

       if(android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) { 
        bitmapFile = new File(pathToSave, fileName + MagazinePage.FILE_EXT); 
        MainApp.encryptToFile(bitmapFile, is); 
        dwnlSize += bitmapFile.length(); 
       } 
       is.close(); 
      } 
     } 
    } 

    public static void encryptToFile(File file, InputStream is) throws IOException {   
    BufferedOutputStream os = null; 
     try { 
      if (file.exists()) { 
       file.delete(); 
      } else { 
       file.getParentFile().mkdirs(); 
      } 
      file.createNewFile(); 
      os = new BufferedOutputStream(new FileOutputStream(file)); 
      IkioskContentProvider.getInstance().encrypt(is, os); 
     } finally { 
      os.close(); 
     } 
    } 
} 

DownloadRunnable是定製實現Runnable的抽象類。而且我用它在線程的常規方式:

protected void downloadIssuePages() { 
    dwnlTask = new DownloadTask(); 
    new Thread(dwnlTask).start(); 
} 

我打電話downloadIssuePages()兩個不同對象上下載兩套例子。

使用SDK版本11(安卓3.0),設備宏碁ICONIA TAB A500採用Android 3.1

+0

我有一個理論,它爲什麼可能發生的,當你使用線程,他們有時overrite每個人的數據換句話說,他們可能會寫入相同的文件名或相同的內存位置或類似的東西,通常做這樣的事情,我會建議使用鎖,但我不知道你在做什麼鎖,我仍然是新的移動dev – Armand

+0

感謝您的提示,我得出了同樣的結論。但問題是這些線程正在寫入不同的文件,因此它們不應該相互衝突。顯然,這些流的數據流中有些衝突或什麼。寫入文件時我現在使用了鎖定,看起來像是有效。 – Speedy

回答

1

我試圖禁用寫第二個線程,只有第一個線程保存文件,以找出是否有一個在閱讀流或寫作時遇到的問題。在這種情況下,數據顯然是正確的問題。

所以我決定用鎖各地寫入文件,看起來像它的正常工作:

synchronized (MainApp.fileWritingLockObj) { 
    while (MainApp.fileWritingLocked) { 
     try { 
      MainApp.fileWritingLockObj.wait(); 
     } catch (InterruptedException e) { 
     }        
    } 
    MainApp.fileWritingLocked = true;       
    if(android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) { 
     bitmapFile = new File(pathToSave, fileName + MagazinePage.FILE_EXT); 
     MainApp.encryptToFile(bitmapFile, is); 
     dwnlSize += bitmapFile.length(); 
    } 
    is.close(); 
    MainApp.fileWritingLocked = false; 
    MainApp.fileWritingLockObj.notifyAll(); 
}