2009-07-15 5 views
1

Я строю систему на Java, которая должна скопировать подмножество файла в другой файл (не обязательно в начало файла). То есть У меня есть следующие параметры:Эффективная копия из одного файла в другой

File srcFile, File dstFile, long srcFileOffset, long dstFileOffset, long length

Несколько потоков могут быть чтение из того же исходного файла и производя запись в том же направлении-файл (хотя и с разными сдвигами) simultaneosuly так что мне нужен, чтобы этот процесс резьбовыми безопасный (т. е. предотвращение поиска других потоков в файле при записи/чтении потока).

Как вы это реализуете? Должен ли я использовать RandomAccessFile или Java NIO? Какие блокировки мне нужно приобрести? Например. экземпляр RandomAccessFile автоматически получает общесистемную блокировку в файле или мне нужно сохранить это отдельно?

Редактировать: Похоже, что randomAccessFile.getChannel().tryLock() приобретает системный замок, но удерживается VM, а не вызывающей нитью. Поэтому, если я использую это, мне также необходимо получить блокировку для потока (или два на самом деле, так как мне нужно заблокировать как исходный, так и целевой файл).

ответ

2

Я составил небольшой тестовый код. Кажется, работает без проблем на WinXP:

import java.io.RandomAccessFile; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 

public class MultiRAF { 
    public static void main(String[] args) throws Exception { 
     RandomAccessFile raf = new RandomAccessFile("testraf.dat", "rw"); 
     raf.setLength(4096); 
     raf.close(); 
     ExecutorService exec = Executors.newCachedThreadPool(); 
     for (int k = 0; k < 4; k++) { 
      final int offset = k * 1024; 
      final int kid = k; 
      exec.submit(new Runnable() { 
       public void run() { 
        try { 
         RandomAccessFile raf = new RandomAccessFile(
          "testraf.dat", "rw"); 
         for (int j = 0; j < 100; j++) { 
          System.out.printf("%d accessing%n", kid); 
          byte[] data = new byte[1024]; 
          for (int i = 0; i < data.length; i++) { 
           data[i] = (byte)i; 
          } 
          raf.seek(offset); 
          raf.write(data); 
          System.out.printf("%d done%n", kid); 
         } 
         raf.close(); 
        } catch (Exception ex) { 
         System.err.printf("%d failed%n", kid); 
         ex.printStackTrace(); 
        } 

       }; 
      }); 
     } 
     exec.shutdown(); 
    } 
} 
+0

Интересно, я полагаю, что позиция, заданная поиском, является локальной для экземпляра RandomAccessFile. Я не знал, что вы можете открыть несколько экземпляров с возможностью записи в один файл и сохранить отдельные позиции в дескрипторе. – Yrlec

1

вы можете просто открыть FileInputStream на srcFile, пропустить (srcFileOffset), и читать оттуда. Но для записи в файле назначения с определенным смещением вам понадобится RandomAccessFile.

Что касается блокировки, вы можете использовать singleton для чтения/записи из файла и синхронизации методов чтения/записи на вашем объекте.

+0

+1. Вероятно, оптимизация случайного доступа также должна улучшить производительность ввода-вывода. – akarnokd

+0

Спасибо, я попробую. Тогда мне просто нужно сохранить данные, прочитанные в каком-то промежуточном буфере, поэтому я не пишу его побайтно в RandomAccessFile. – Yrlec

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