2016-12-13 10 views
0

Как я могу эффективно читать из большого файла и записывать объемные данные в файл с использованием рамки Java NIO.Чтение и написание большого файла с использованием Java NIO

Я работаю с ByteBuffer и FileChannel и пытался что-то вроде ниже:

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 Гб?

Что я должен соблюдать, если аналогичные вещи я хочу делать во время записи, если письменные операции навалом?

+0

Вы пытаетесь обработать данные между ними, или вы просто хотите, чтобы скопировать его? – Kayaman

+1

Что означает «если подобные вещи, которые я хочу сделать»? – EJP

ответ

1

Обратите внимание, что вы можете просто использовать Files.copy(Paths.get(inFileStr),Paths.get(outFileStr), StandardCopyOption.REPLACE_EXISTING), чтобы скопировать файл по вашему примеру, скорее всего, быстрее и только с одной строкой кода.

В противном случае, если вы уже открыли два канала файлов, вы можете просто использовать
in.transferTo(0, in.size(), out) передать все содержимое in канала на out канал. Обратите внимание, что этот метод позволяет указать диапазон в исходном файле, который будет перенесен в текущее положение целевого канала (которое первоначально равно нулю), и что существует также метод для противоположного способа, то есть out.transferFrom(in, 0, in.size()) для передачи данных из текущего канала источника позиции до абсолютного диапазона в целевом файле.

Вместе они позволяют практически любой мыслимый нетривиальный массовый перенос эффективным способом без необходимости копировать данные в боковой буфер Java. Если это не решает ваши потребности, вы должны быть более конкретными в своем вопросе.

Кстати, вы можете open a FileChannel directly без FileInputStream/FileOutputStream объезд, так как 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 Гб?

Да. Размер файла не имеет никакого значения.

+0

Как это изменение повлияет, если размер файла огромен? – KayV

+0

Это гарантирует, что неполные записи не будут потеряны и что прочитанное окончательное произведение будет очищено. Этот код будет работать для любого размера файла с нуля вверх. – EJP

 Смежные вопросы

  • Нет связанных вопросов^_^