2011-07-31 5 views
0

동시에 두 곳에서 파일을 읽고 싶습니다. 또한 효율성을 위해 버퍼 된 I/O 스트림을 사용하려고합니다. 내 자신의 주어진 자바 API에 sth을 해결하려했지만 작동하지 않습니다. 아무도 도와 줄 수 없나요? 외부 병합 정렬을 위해 필요합니다. 도와 주셔서 감사합니다!Java의 서로 다른 두 위치에서 동일한 파일에 액세스하는 방법

+3

왜 동시에 두 위치에서 파일을 읽으시겠습니까? io 증기의 코드/예외 스택 추적이 작동하지 않습니다. – Jeffrey

+0

기본적으로 RandomAccessFile을 사용하려고 시도한 다음 랩핑했습니다. new DataInputStream (new BufferedInputStream (new FileInputStream (file.getFD())))); 여기서 파일은 임의 액세스 파일입니다. 내가 다른 곳에서 파일 블록을 액세스하기 시작할 때마다 나는 RandomAccessFile을 찾고 새로운 래퍼를 만들었다. – nivwusquorum

답변

1

RandomAccessFile을 작성해야합니다. 이는 기본적으로 Java의 C의 메모리 맵핑 파일과 동일합니다. 이의 I found an example

:

try { 
    File file = new File("filename"); 

    // Create a read-only memory-mapped file 
    FileChannel roChannel = new RandomAccessFile(file, "r").getChannel(); 
    ByteBuffer roBuf = roChannel.map(FileChannel.MapMode.READ_ONLY, 0, (int)roChannel.size()); 

    // Create a read-write memory-mapped file 
    FileChannel rwChannel = new RandomAccessFile(file, "rw").getChannel(); 
    ByteBuffer wrBuf = rwChannel.map(FileChannel.MapMode.READ_WRITE, 0, (int)rwChannel.size()); 

    // Create a private (copy-on-write) memory-mapped file. 
    // Any write to this channel results in a private copy of the data. 
    FileChannel pvChannel = new RandomAccessFile(file, "rw").getChannel(); 
    ByteBuffer pvBuf = roChannel.map(FileChannel.MapMode.READ_WRITE, 0, (int)rwChannel.size()); 
} catch (IOException e) { 
} 

편집, 당신은 당신이 건너 뛰고 아래 파일을 통해 할 수있는 유일한 방법입니다 RandomAccessFile를 사용할 수 없습니다 말했다. 파일이 없으면 파일을 순차적으로 읽어야하지만, 그렇다고해서 동일한 파일에 대해 여러 개의 포인터를 열어 읽을 수는 없습니다.

다음 테스트/샘플을 함께 넣으면 다른 읽기 포인터로 "두 번"파일을 열고 파일의 두 부분을 순차적으로 합할 수 있음을 분명히 보여줍니다. 당신이 랜덤 액세스 필요하면 다시, 당신은 RandomAccessFile를 사용해야하며, 그것이 내가 좋을 것 무엇, 그러나 여기 당신은 간다 :

단순히 두 번 파일을 열 및 작업에서 당신을 중지 무엇
public class FileTest { 

    public static void main(String[] args) throws IOException, InterruptedException, ExecutionException{ 

     File temp = File.createTempFile("asfd", ""); 
     BufferedWriter wrt = new BufferedWriter(new FileWriter(temp)); 

     int testLength = 10000; 
     int numWidth = String.valueOf(testLength).length(); 

     int targetSum = 0; 
     for(int i = 0; i < testLength; i++){ 
      // each line guaranteed to have a good number of characters for our test 
      wrt.write(String.format("%0"+ numWidth +"d\n", i)); 
      targetSum += i; 
     } 
     wrt.close(); 

     BufferedReader rdr1 = new BufferedReader(new FileReader(temp)); 
     BufferedReader rdr2 = new BufferedReader(new FileReader(temp)); 

     rdr2.skip((numWidth+1)*testLength/2); // skip first half of the lines 

     Summer sum1 = new Summer(rdr1, testLength/2); 
     Summer sum2 = new Summer(rdr2, testLength/2); 

     ExecutorService executor = Executors.newFixedThreadPool(2); 
     Future<Integer> halfSum1 = executor.submit(sum1); 
     Future<Integer> halfSum2 = executor.submit(sum2); 

     System.out.println("Total sum = " + (halfSum1.get() + halfSum2.get()) + " reference " + targetSum); 

     rdr1.close(); 
     rdr2.close(); 

     temp.delete(); 
    } 

    private static class Summer implements Callable<Integer>{ 
     private BufferedReader rdr; 
     private int limit; 

     public Summer(BufferedReader rdr, int limit) throws IOException{ 
      this.rdr = rdr; 
      this.limit = limit; 
     } 

     @Override 
     public Integer call() throws Exception { 
      System.out.println(Thread.currentThread().getName() + " started " + System.currentTimeMillis()); 
      int sum = 0; 
      for(int i = 0; i < limit; i++){ 
       sum += Integer.valueOf(rdr.readLine()); 
       // uncomment to see interleaving of threads: 
       //System.out.println(Thread.currentThread().getName()); 
      } 
      System.out.println(Thread.currentThread().getName() + " finished " + System.currentTimeMillis()); 
      return sum; 
     } 

    } 

} 
+0

오, 그래, 나는 기억지도가 허용되지 않는다 :(그것은 대학 과제를위한 것이고, 나의 유니는 약간 지체가 있으며, 메모리 맵이 허용되는 경우 메모리를 제한하는 방법을 모르고있다 .. – nivwusquorum

+0

"제한 기억"? –

0

마치 두 개의 독립적 인 파일 인 것처럼?

 File inputFile = new File("src/SameFileTwice.java"); 
    BufferedReader in1 = new BufferedReader(new InputStreamReader(new FileInputStream(inputFile))); 
    BufferedReader in2 = new BufferedReader(new InputStreamReader(new FileInputStream(inputFile))); 
    try { 
     String strLine; 
     while ((strLine = in1.readLine()) != null && (strLine = in2.readLine()) != null) { 
      System.out.println(strLine); 
     } 
    } finally { 
     in1.close(); 
     in2.close(); 
    } 
관련 문제