Как получить доступ к одному и тому же файлу в двух разных местах в Java - PullRequest
0 голосов
/ 01 августа 2011

Я хочу читать из файла из двух разных мест одновременно.Я также хочу использовать буферизованный поток ввода-вывода для эффективности.Я пытался отработать STH на своем собственном Java API, но это не работает.Кто-нибудь поможет?Мне это нужно для внешней сортировки слиянием.Спасибо за помощь!

Ответы [ 2 ]

1 голос
/ 01 августа 2011

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

I нашел пример этого:

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 голосов
/ 02 августа 2011

Что мешает вам просто дважды открыть файл и работать с ним, как если бы это были два независимых файла?

        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();
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...