2016-03-29 11 views
0

大きなファイルを効率的に転送したいので、ファイル転送にはjava.io.RandomAccessFilejava.nio.channels.FileChannelを使用します。私の出力ファイルのサイズがオリジナルファイルよりも小さいのはなぜですか?

出力ファイルが正しくありません。これは、元のソースファイルよりも小さくなっています。ここでは、コードは次のとおりです。

public static void transferByRandomAccess(String inputFile, String outputFile) throws IOException { 
     RandomAccessFile inputRandomAccessFile = null; 
     RandomAccessFile outputRandomAccessFile = null; 
     try { 
      inputRandomAccessFile = new RandomAccessFile(inputFile, "r"); 
      FileChannel inputFileChannel = inputRandomAccessFile.getChannel(); 
      outputRandomAccessFile = new RandomAccessFile(outputFile, "rw"); 
      FileChannel outFileChannel = outputRandomAccessFile.getChannel(); 
      inputFileChannel.transferTo(0, inputFileChannel.size(), outFileChannel); 
      inputFileChannel.force(true); 
      outFileChannel.force(true);   
     } finally { 
      if (outputRandomAccessFile != null) { 
       outputRandomAccessFile.close(); 
      } 
      if (inputRandomAccessFile != null) { 
       inputRandomAccessFile.close(); 
      } 
     } 
    } 

ちなみに、私の入力ファイルは、そのサイズが2937236651バイトであるMKVビデオファイル、です。そして、私はjava.io.BufferedInputStreamjava.io.BufferedOutputStreamとそれをコピーしている間、問題はありません。

+0

私はあなたのコードを試しましたが、それはうまくいきます、違いは何ですか? – VinhNT

+0

@VinhNT違いはなく、関数をコピーしてここに貼り付けます。 –

+0

私はC:\ file1.zipでC:\ file2.zipを試してみましたが、アプリケーションの前にはC:\ file2.zipがありません。その後、file2.zipが作成され、同じサイズ(バイト単位)でfile1.zip – VinhNT

答えて

1

あなたの新しいアップデートでは、ファイルが2GBを超えています。このような操作のためのバッファを作成するにはOSの制限があります。この場合、アプリケーションを更新して、2GBを超えるファイルで動作するようにする必要があります。

public class Test { 

    public static void main(String[] args) throws Exception { 
     RandomAccessFile inputRandomAccessFile = null; 
     RandomAccessFile outputRandomAccessFile = null; 
     try { 
      inputRandomAccessFile = new RandomAccessFile("G:\\file1.zip", "r"); 
      FileChannel inputFileChannel = inputRandomAccessFile.getChannel(); 
      outputRandomAccessFile = new RandomAccessFile("G:\\file2.zip", "rw"); 
      FileChannel outFileChannel = outputRandomAccessFile.getChannel(); 
      long readFileSize = inputFileChannel.size(); 
      long transferredSize = 0; 
      do { 
       long count = inputFileChannel.transferTo(transferredSize, inputFileChannel.size(), outFileChannel); 
       transferredSize += count; 
      } while (transferredSize < readFileSize); 

      inputFileChannel.force(true); 
      outFileChannel.force(true); 
     } finally { 
      if (outputRandomAccessFile != null) { 
       outputRandomAccessFile.close(); 
      } 
      if (inputRandomAccessFile != null) { 
       inputRandomAccessFile.close(); 
      } 
     } 
     System.out.println("DONE"); 
    } 
} 
1

コピー手順が間違っています。 transferTo()は、1回のコールで入力全体を転送するように指定されていません。それがカウントを返す理由です。あなたは、転送する余地がなくなるまで、オフセットを進め、長さを減らしてループする必要があります。

関連する問題