2009-07-15 217 views
1

我正在用Java构建一个系统,它必须将文件的一个子集复制到另一个文件(不一定是文件的开头)。即我有以下参数:从一个文件到另一个文件的高效复制

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

的多个线程可以从相同的源文件进行读取和写入到相同的目的地文件(虽然具有不同的偏移)simultaneosuly所以我需要的过程是thread-安全(即在线程正在写入/读取时阻止其他线程在文件中查找)。

你将如何实现这一点?我应该使用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

有趣的是,我猜由seek设置的位置对于RandomAccessFile实例是本地的。我不知道你可以用同一个文件的写入权限打开多个实例,并且仍然在描述符中保留单独的位置。 – Yrlec 2009-07-15 22:19:34

1

,你可以打开一个FileInputStream上SRCFILE,跳过(srcFileOffset),并从那里读取。但要以某个偏移量写入目标文件,您需要使用RandomAccessFile。至于锁定,您可以使用一个单例来读取/写入文件并同步对象上的读/写方法。

+0

+1。随机访问的简化可能也会改善IO性能。 – akarnokd 2009-07-15 20:54:00

相关问题