2011-09-13 14 views
0

イメージのセットを別々のスレッドにダウンロードし、SDカードに保存します。問題は、2つ以上のダウンロードスレッドを実行すると、保存されたイメージが壊れてしまうことです。 1つのスレッドしか実行されていない場合、イメージは正常です。私は同じドメインからダウンロードしていますが、別のURL(例: 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(); 
} 

私は例えば2セットをダウンロードするには2つの異なるオブジェクト上のdownloadIssuePages()を呼んでいます。

SDKのバージョン11(アンドロイド3.0)私は2番目のスレッドの書き込みを無効にしようとしたアンドロイド3.1

+0

あなたがスレッドを使用する場合、それは、起こってかもしれない、なぜ私は理論を持っているし、彼らは時々overriteお互いのデータをすることができます言い換えれば、同じファイル名や同じメモリ位置などに書き込んでいる可能性があります。通常、このようなことをするにはロックを使用するようにアドバイスしますが、あなたがやっていることに対するロックについてはわかりません。モバイルデベロッパー – Armand

+0

チップをありがとう、私は同じ結論に来た。しかし、問題は、これらのスレッドが異なるファイルに書き込んでいるため、衝突しないようにすることです。どうやらストリームのデータフローに何か衝突があります。私はファイルに書き込むときにロックを使用し、それが動作するように見えます。 – Speedy

答えて

1

と、デバイスエイサーIconiaタブA500を使用して、最初のスレッドがありますかどうかを確認するためにファイルを保存しましたストリームからの読み込みや書き込みに問題があります。このケースではデータが正しいので、明らかに書き込みが問題でした。

だから私は、ファイルへの書き込みの周りにロックを使用することを決定し、それがうまく働いているように見えます:

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(); 
} 
関連する問題