Подтвердить что ты не робот

Параллельное чтение файла (с использованием java)

У меня есть большой файл, который обрабатывает несколько часов. Поэтому я собираюсь попытаться оценить куски и прочитать куски параллельно. возможно ли одновременное чтение одного файла? Я посмотрел как на RandomAccessFile, так и на nio.FileChannel, но на основе других сообщений я не уверен, что этот подход будет работать. предложение!!

4b9b3361

Ответ 1

Самый важный вопрос здесь - , что является узким местом в вашем случае.

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

Если узкое место мощность обработки, и у вас есть несколько ядер процессора, то вы можете воспользоваться преимуществами запуска нескольких потоков для работы в разных частях файла. Вы можете безопасно создать несколько InputStream или Reader, чтобы читать разные части файла параллельно (если вы не перейдете к пределу операционной системы для количества открытых файлов). Вы можете разделить работу на задачи и запустить их параллельно, как в этом примере:

import java.io.*;
import java.util.*;
import java.util.concurrent.*;

public class Split {
    private File file;

    public Split(File file) {
        this.file = file;
    }

    // Processes the given portion of the file.
    // Called simultaneously from several threads.
    // Use your custom return type as needed, I used String just to give an example.
    public String processPart(long start, long end)
        throws Exception
    {
        InputStream is = new FileInputStream(file);
        is.skip(start);
        // do a computation using the input stream,
        // checking that we don't read more than (end-start) bytes
        System.out.println("Computing the part from " + start + " to " + end);
        Thread.sleep(1000);
        System.out.println("Finished the part from " + start + " to " + end);

        is.close();
        return "Some result";
    }

    // Creates a task that will process the given portion of the file,
    // when executed.
    public Callable<String> processPartTask(final long start, final long end) {
        return new Callable<String>() {
            public String call()
                throws Exception
            {
                return processPart(start, end);
            }
        };
    }

    // Splits the computation into chunks of the given size,
    // creates appropriate tasks and runs them using a 
    // given number of threads.
    public void processAll(int noOfThreads, int chunkSize)
        throws Exception
    {
        int count = (int)((file.length() + chunkSize - 1) / chunkSize);
        java.util.List<Callable<String>> tasks = new ArrayList<Callable<String>>(count);
        for(int i = 0; i < count; i++)
            tasks.add(processPartTask(i * chunkSize, Math.min(file.length(), (i+1) * chunkSize)));
        ExecutorService es = Executors.newFixedThreadPool(noOfThreads);

        java.util.List<Future<String>> results = es.invokeAll(tasks);
        es.shutdown();

        // use the results for something
        for(Future<String> result : results)
            System.out.println(result.get());
    }

    public static void main(String argv[])
        throws Exception
    {
        Split s = new Split(new File(argv[0]));
        s.processAll(8, 1000);
    }
}

Ответ 2

Вы можете параллельно читать большой файл, если у вас несколько независимых шпинделей. Например. если у вас есть файловая система Raid 0 + 1, вы можете увидеть улучшение производительности путем запуска нескольких одновременных чтений в один и тот же файл.

Если у вас есть объединенная файловая система, такая как Raid 5 или 6 или простой одиночный диск. Весьма вероятно, что чтение файла последовательно является самым быстрым способом чтения с этого диска. Примечание. ОС достаточно умна, чтобы предварительно считывать показания, когда видит, что вы читаете последовательно, поэтому использование дополнительного потока для этого вряд ли поможет.

то есть. использование нескольких потоков не сделает вас быстрее.

Если вы хотите быстрее читать с диска, используйте более быстрый диск. Типичный жесткий диск SATA может считывать около 60 МБ/с и выполнять 120 IOPS. Типичный SSD-накопитель SATA может считывать около 400 МБ/с и выполнять 80 000 операций ввода-вывода, а типичный PCI SSD может считывать со скоростью 900 МБ/с и выполнять 230 000 IOPS.

Ответ 3

Если вы читаете файл с жесткого диска, то самый быстрый способ получить данные - это прочитать файл от начала до конца, то есть не одновременно.

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

Ответ 4

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