2011-12-22 11 views
29

p2pダウンロードソフトウェアを使用したことがある人は、マルチスレッドでファイルをダウンロードでき、ファイルは1つしか作成できないため、スレッドがそのファイルにデータを書き込む方法が不思議です。シーケンシャルまたはパラレル?複数のスレッドが同時にファイルにデータを書き込むことはできますか?

大きなデータベーステーブルをファイルにダンプし、このジョブを高速化する方法を想像してみてください。

+13

はい、可能ですが、実際にはまったく同じことをしないようにしたいと考えています。いくつかの調整が必要です。 Bittorrentについて話しているのであれば、既知のオフセットのブロックを既知のサイズのファイルに組み立てることで動作すると思います。シーケンシャルまたはパラレルに呼び出すことはできませんが、それはより「ランダムアクセス」です。 – Thilo

+0

似たような質問:http://stackoverflow.com/questions/6206472/what-is-the-best-way-to-write-to-a-file-in-a-parallel-thread-in-java – Vadzim

答えて

21

ファイルにaを書き込む複数のスレッドを使用できます。ログファイル。 @Thiloが指摘するようにスレッドを調整する必要があります。ファイルアクセスを同期させ、レコード/行全体を書き込む必要があるか、ファイルの領域を別のスレッドに割り当てる戦略が必要です。既知のオフセットとサイズのファイルを再構築する。

これはほとんどのディスクサブシステムが順番に書き込まれ、ディスクIOがボトルネックであるときに最高のパフォーマンスを発揮するため、パフォーマンスの理由からめったに実行されません。レコードやテキスト行(またはネットワークIO)を作成するCPUがボトルネックになっている場合は、それが役に立ちます。

大きなデータベーステーブルをファイルにダンプするイメージと、このジョブを高速化する方法はありますか。

これを順番に書き込む方が高速です。

+0

semaphore –

0

同じファイルに複数のスレッドを書き込むことができますが、一度に1つずつ行うことができます。すべてのスレッドは、ファイルに書き込む前に同期ブロックを入力する必要があります。

P2Pの例では、実装する方法の1つは、ファイルのサイズを見つけてそのサイズの空のファイルを作成することです。各スレッドは、ファイルの異なるセクションをダウンロードしています。書き込みが必要な場合は、同期ブロックに入ります。シークを使用してファイルポインタを移動し、バッファの内容を書き込みます。

+0

"すべてのスレッドは、ファイルに書き込む前に同期ブロックを入力する必要があります。"まあ、彼らは*持っていない*。しかし、あなたは出力が好きではなく、面白​​いやり方でインターリーブすることができます。 – Thilo

18

Java nioパッケージはこれを可能にするように設計されています。たとえば、http://docs.oracle.com/javase/1.5.0/docs/api/java/nio/channels/FileChannel.htmlを見てください。

1つのファイルの複数の領域を異なるバッファにマップすることができます。各バッファは別々のスレッドで別々に埋め込むことができます。

+2

+1 Javaでこの「P2Pダウンロードソフトウェア」を実装したい場合は、使用するには良いAPIのようです。 – Thilo

1

どのようなファイルですか?なぜあなたはそれにもっと多くのスレッドを供給する必要がありますか?それはファイルの使用の特性(私はそれのためのよりよい言葉を知らない)によって決まります。ネットワーク上の複数の場所からファイルを転送

(ショート:-ようなトレント)

既存のファイルを転送している場合は、プログラムすべきとすぐに、それは知っているにつれて

  • ファイルのサイズ、空の内容でそれを作成する:これは後でディスクが足りないことを防ぎます(十分なスペースがない場合は、そのファイルをダウンロードする前に作成時に表示されます)。
  • もし、何か2つのスレッドがファイルの同じ部分を選んだとしても、転送がうまく整理されていれば、各スレッドはファイルの別個の部分を担当しますので、ファイル書き込みは別々になります(
  • )同じファイル位置に対して同じデータを書き込むため、エラーは発生しません。
  • ファイル(ショート:ログ)へのデータ・ブロックを追加は

スレッドは単にファイルへの固定や各種-な長さの情報を付加した場合は、共通のスレッドを使用する必要があります。比較的大きな書き込みバッファを使用する必要があるため、クライアントスレッドを素早く(文字列を取るだけで)処理し、最適なスケジューリングとブロックサイズをフラッシュすることができます。それは専用のディスクまたはコンピュータを使用する必要があります。

また、いくつかのパフォーマンス上の問題がある可能性があります。そのため、ローカルサーバー、さらには高価な市販のものもあります。

読書とランダムな時間を書いて、ランダムな位置(ショート:データベース)

これは、ミューテックスなどで、私はこのちょっとものをやったことがないが、私は想像することができ、複雑な設計を必要とします。オラクルにいくつかのトリックをお尋ねください:)

2

これを行うには、同期宣言が可能です。同様の文脈で私が使用する以下のコードを試してみてください。

package hrblib; 

import java.io.*; 

public class FileOp { 

    static int nStatsCount = 0; 

    static public String getContents(String sFileName) { 

     try { 
      BufferedReader oReader = new BufferedReader(new FileReader(sFileName)); 
      String sLine, sContent = ""; 
      while ((sLine=oReader.readLine()) != null) { 
       sContent += (sContent=="")?sLine: ("\r\n"+sLine); 
      } 
      oReader.close(); 
      return sContent; 
     } 
     catch (IOException oException) { 
      throw new IllegalArgumentException("Invalid file path/File cannot be read: \n" + sFileName); 
     } 
    } 
    static public void setContents(String sFileName, String sContent) { 
     try { 
      File oFile = new File(sFileName); 
      if (!oFile.exists()) { 
       oFile.createNewFile(); 
      } 
      if (oFile.canWrite()) { 
       BufferedWriter oWriter = new BufferedWriter(new FileWriter(sFileName)); 
       oWriter.write (sContent); 
       oWriter.close(); 
      } 
     } 
     catch (IOException oException) { 
      throw new IllegalArgumentException("Invalid folder path/File cannot be written: \n" + sFileName); 
     } 
    } 
    public static synchronized void appendContents(String sFileName, String sContent) { 
     try { 

      File oFile = new File(sFileName); 
      if (!oFile.exists()) { 
       oFile.createNewFile(); 
      } 
      if (oFile.canWrite()) { 
       BufferedWriter oWriter = new BufferedWriter(new FileWriter(sFileName, true)); 
       oWriter.write (sContent); 
       oWriter.close(); 
      } 

     } 
     catch (IOException oException) { 
      throw new IllegalArgumentException("Error appending/File cannot be written: \n" + sFileName); 
     } 
    } 
} 
関連する問題