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

Может ли несколько потоков записывать данные в файл одновременно?

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

Представьте, что вы хотите сбросить большую таблицу базы данных в файл и как сделать эту работу быстрее?

4b9b3361

Ответ 1

Вы можете использовать несколько потоков, записывающих файл в файл, например. файл журнала. но вы должны координировать свои потоки, как указывает @Thilo. Либо вам нужно синхронизировать доступ к файлам, и только писать целые записи/строки, или вам нужно иметь стратегию для распределения областей файла на разные потоки, например. пересоздание файла с известными смещениями и размерами.

Это редко делается по соображениям производительности, поскольку большинство дисковых подсистем лучше всего работают, когда записываются последовательно, а диск IO является узким местом. Если ЦП для создания записи или строки текста (или сетевого ввода-вывода) является узким местом, это может помочь.

Изображение, которое вы хотите выгрузить большую таблицу базы данных в файл, и как сделать эту работу быстрее?

Написание его последовательно, скорее всего, будет самым быстрым.

Ответ 2

Java nio-пакет был разработан для этого. Посмотрите, например, на http://docs.oracle.com/javase/1.5.0/docs/api/java/nio/channels/FileChannel.html.

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

Ответ 3

Синхронизированное объявление позволяет это сделать. Попробуйте использовать приведенный ниже код, который я использую в подобном контексте.

package hrblib;

import java.io.*;

public class FileOp {

    static int nStatsCount = 0;

    static public String getContents(String sFileName) {  

        try {
            BufferedReader oReader = new BufferedReader(new FileReader(sFileName));
            String sLine, sContent = "";
            while ((sLine=oReader.readLine()) != null) {
                sContent += (sContent=="")?sLine: ("\r\n"+sLine);
            }
            oReader.close();
            return sContent;
        }
        catch (IOException oException) {
            throw new IllegalArgumentException("Invalid file path/File cannot be read: \n" + sFileName);
        }
    }
    static public void setContents(String sFileName, String sContent) {
        try {
            File oFile = new  File(sFileName);
            if (!oFile.exists()) {
                oFile.createNewFile();
            }
            if (oFile.canWrite()) {
                BufferedWriter oWriter = new BufferedWriter(new FileWriter(sFileName));
                oWriter.write (sContent);
                oWriter.close();
            }
        }
        catch (IOException oException) {
            throw new IllegalArgumentException("Invalid folder path/File cannot be written: \n" + sFileName);
        }
    }
    public static synchronized void appendContents(String sFileName, String sContent) {
        try {

            File oFile = new File(sFileName);
            if (!oFile.exists()) {
                oFile.createNewFile();
            }
            if (oFile.canWrite()) {
                BufferedWriter oWriter = new BufferedWriter(new FileWriter(sFileName, true));
                oWriter.write (sContent);
                oWriter.close();
            }

        }
        catch (IOException oException) {
            throw new IllegalArgumentException("Error appending/File cannot be written: \n" + sFileName);
        }
    }
}

Ответ 4

Что это за файл? Зачем вам нужно подавать больше потоков? Это зависит от характеристик (я не знаю лучшего слова для этого) использования файла.

Перенос файла из нескольких мест по сети (короткий: Torrent-like)

Если вы переносите существующий файл, программа должна

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

Добавление блоков данных в файл (короткие: протоколирование)

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

Кроме того, может быть несколько проблем с производительностью, поэтому есть серверы журналов, даже дорогие коммерческие.

Чтение и запись случайного времени, случайная позиция (короткая: база данных)

Это требует сложного дизайна, с мьютексами и т.д., я никогда не делал этого рода, но могу себе представить. Спросите Oracle о некоторых трюках:)

Ответ 5

Можно записать несколько потоков в один и тот же файл, но один за раз. Все записи должны будут ввести синхронизированный блок перед записью в файл.

В примере P2P - один из способов реализовать его - найти размер файла и создать пустой файл такого размера. Каждый поток загружает разные разделы файла - когда им нужно писать, они войдут в синхронизированный блок - переместите указатель файла, используя поиск и запись содержимого буфера.