2016-12-13 12 views
0

Java NIOフレームワークを使用して、大きなファイルから効果的に読み込み、バルクデータをファイルに書き込むにはどうすればよいですか。Java NIOを使用して大きなファイルを読み書きする

私はByteBufferFileChannelで働いていると、以下のようなものを試してみました:

public static void main(String[] args) 
{ 
    String inFileStr = "screen.png"; 
    String outFileStr = "screen-out.png"; 
    long startTime, elapsedTime; 
    int bufferSizeKB = 4; 
    int bufferSize = bufferSizeKB * 1024; 

    // Check file length 
    File fileIn = new File(inFileStr); 
    System.out.println("File size is " + fileIn.length() + " bytes"); 
    System.out.println("Buffer size is " + bufferSizeKB + " KB"); 
    System.out.println("Using FileChannel with an indirect ByteBuffer of " + bufferSizeKB + " KB"); 

    try ( FileChannel in = new FileInputStream(inFileStr).getChannel(); 
      FileChannel out = new FileOutputStream(outFileStr).getChannel()) 
    { 
     // Allocate an indirect ByteBuffer 
     ByteBuffer bytebuf = ByteBuffer.allocate(bufferSize); 

     startTime = System.nanoTime(); 

     int bytesCount = 0; 
     // Read data from file into ByteBuffer 
     while ((bytesCount = in.read(bytebuf)) > 0) { 
      // flip the buffer which set the limit to current position, and position to 0. 
      bytebuf.flip(); 
      out.write(bytebuf); // Write data from ByteBuffer to file 
      bytebuf.clear(); // For the next read 
     } 

     elapsedTime = System.nanoTime() - startTime; 
     System.out.println("Elapsed Time is " + (elapsedTime/1000000.0) + " msec"); 
    } 
    catch (IOException ex) { 
     ex.printStackTrace(); 
    } 
} 

誰もがあれば、私は、同じ手順に従うべきで、言うことができる2 GB以上の私のファイルサイズは?

書面による操作が一括して行われているのと同様のことを書いていたら、私は何をしたいのですか?

+0

以来FileInputStream/FileOutputStream迂回せずにopen a FileChannel directlyをしようとしていますすることができ、またはあなたはそれをコピーしたいのですか? – Kayaman

+1

「私がしたいと思っているものが類似している」とはどういう意味ですか? – EJP

答えて

1

Files.copy(Paths.get(inFileStr),Paths.get(outFileStr), StandardCopyOption.REPLACE_EXISTING)を使用すると、サンプルコードのようにファイルをコピーすることができます。コードが1行だけで高速になる可能性があります。

すでに2つのファイルのチャンネルを開いている場合はそれ以外の場合は、あなただけのoutチャンネルにinチャンネルの内容全体を転送する
in.transferTo(0, in.size(), out)を使用することができます。このメソッドでは、ソースファイル内でターゲットチャネルの現在の位置(最初は0)に転送される範囲を指定することができます。逆の方法もあります。out.transferFrom(in, 0, in.size())はソースチャネルの現在のデータからデータを転送しますターゲットファイル内の絶対範囲に配置します。

これらは一緒になって、データをJava側のバッファにコピーする必要なく、効率的な方法でほぼすべての重要なバルク転送を可能にします。それがあなたのニーズを解決していないなら、あなたはあなたの質問にもっと具体的でなければなりません。ところで

、あなたは間でデータを処理するためにJava 7

0
while ((bytesCount = in.read(bytebuf)) > 0) { 
     // flip the buffer which set the limit to current position, and position to 0. 
     bytebuf.flip(); 
     out.write(bytebuf); // Write data from ByteBuffer to file 
     bytebuf.clear(); // For the next read 
    } 

コピーループが正しくありません。誰もが言うことができる

while ((bytesCount = in.read(bytebuf)) > 0 || bytebuf.position() > 0) { 
     // flip the buffer which set the limit to current position, and position to 0. 
     bytebuf.flip(); 
     out.write(bytebuf); // Write data from ByteBuffer to file 
     bytebuf.compact(); // For the next read 
    } 

、私のファイルサイズの2 GB以上[がある]場合、私は、同じ手順に従ってください:それはすべきですか?

はい。ファイルサイズは違いはありません。

+0

ファイルサイズが大きい場合、この変更はどのように影響しますか? – KayV

+0

これは、不完全な書き込みが失われず、最後の読み取りがフラッシュされることを保証します。このコードはゼロから上の任意のファイルサイズで機能します。 – EJP

関連する問題