powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / RandomAccessFile
37 сообщений из 37, показаны все 2 страниц
RandomAccessFile
    #38405336
sharmanka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет.
Известно что в файл пишут несколько нитей. Подскажите, как к гарантировано писать в конец файла. Перестановка указателя в конец файла не помогает, все равно часть данных затирается.
Метод ран:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
public void run() {
       RandomAccessFile raf = null;
       
        try {
            raf = new RandomAccessFile("file.txt", "rw");
        } catch (FileNotFoundException ex) {   }
        Random ch = new Random();
        try {

            for (int i = 0; i < Main.bytenum; i++) {
                raf.seek(raf.length());
                raf.writeChar(ch.nextInt());
                
            }
            raf.close();
			
		}
	}
...
Рейтинг: 0 / 0
RandomAccessFile
    #38405440
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sharmankaИзвестно что в файл пишут несколько нитей. Подскажите, как к гарантировано писать в конец файла. Перестановка указателя в конец файла не помогает, все равно часть данных затирается. Во-первых, нужно вынести за пределы метода run() (и класса Runnable) инициализацию переменной RandomAccessFile raf .
Ну, и во-вторых, синхронизировать потоки.
Например:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
final RandomAccessFile raf = new RandomAccessFile("file.txt", "rw");
final Random ch = new Random();
final Object monitor = new Object();
...
new Runnable() {
    public void run() {
        synchronized(monitor) {
            for (int i = 0; i < Main.bytenum; i++) {
                raf.write(ch.nextInt());
            }
        }
    }
}
...
raf.close();

P.S.
http://www.skipy.ru/technics/synchronization.html#monitors
...
Рейтинг: 0 / 0
RandomAccessFile
    #38405853
jdroid
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
выделить работу с файлом в отдельный сервис и всем нитям работать с файлом только через сервис
...
Рейтинг: 0 / 0
RandomAccessFile
    #38405895
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jdroidвыделить работу с файлом в отдельный сервис и всем нитям работать с файлом только через сервис
Ага. Вот такой сервис:
Код: java
1.
ExecutorService service = Executors.newSingleThreadExecutor();
...
Рейтинг: 0 / 0
RandomAccessFile
    #38405935
jdroid
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
думаю лучше будет написать сервис с правильной синхронизацией операций записи
...
Рейтинг: 0 / 0
RandomAccessFile
    #38405944
sharmanka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Usman http://www.skipy.ru/technics/synchronization.html#monitors

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

jdroidвыделить работу с файлом в отдельный сервис и всем нитям работать с файлом только через сервис
У меня и так было выделено:

Код: java
1.
2.
3.
4.
ExecutorService exec = Executors.newFixedThreadPool(num);
        for (int i = 0; i < num; i++) {
            Future f1 = exec.submit(bt);
        }



Проблема актуальна :(
...
Рейтинг: 0 / 0
RandomAccessFile
    #38405953
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так в чем проблема то? Вам уже дали корректный ответ: необходимо синхронизировать операцию записи, что бы одновременно мог писать только один поток. Других решений здесь нет.
...
Рейтинг: 0 / 0
RandomAccessFile
    #38405963
sharmanka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
cdtyjvТак в чем проблема то? Вам уже дали корректный ответ: необходимо синхронизировать операцию записи, что бы одновременно мог писать только один поток. Других решений здесь нет.
Мне нужно писать в несколько потоков и 100% такое решение есть, потому что я видел рабочую программу. Осталось дело за малым - написать такую же.
...
Рейтинг: 0 / 0
RandomAccessFile
    #38405971
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sharmankaТо есть насколько я понял, выходит обычная однопоточная запись в файл, а мне нужно другое.

Какое, нафиг, "другое"? Логически подумай как два потока могут одновременно записать в конец файла, если запись изменяет позицию конца? В любом случае нужна очередь. Если нужно всё это дело жутко заопимтимизировать, то можно взять AtomicInteger в котором трекать длину файла при каждой записи. Если запись производится в конец, то AtomicInteger инкрементируется на длину добавляемого блока. В качестве конца файла все потоки должны использовать этот AtomicInteger.

Но такая оптимизация, ИМХО, особого смысла не имеет. Запись в файл намного медленнее чем блогикровки или другая синхронизация. Особенно если там HDD . Возможно если там SDD или виртуальный диск, и то не факт. Там ещё файловая система с операционкой много чего могут заблокировать.
...
Рейтинг: 0 / 0
RandomAccessFile
    #38405975
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sharmankaМне нужно писать в несколько потоков

Именно в конец файла?

sharmankaи 100% такое решение есть

100% есть готовое или 100% можно реализовать?

sharmankaпотому что я видел рабочую программу.
Откуда вы знаете как она устроена?

sharmankaОсталось дело за малым - написать такую же.
Осталось дело за малым синхронизировать запись в конце файла - не важно каким способом.
...
Рейтинг: 0 / 0
RandomAccessFile
    #38405981
sharmanka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczМне нужно писать в несколько потоков
Именно в конец файла?
Это не уточняется, я думаю можно писать в любое место, главное чтобы предыдущие записи не затирались.

Blazkowicz100% есть готовое или 100% можно реализовать?
готовое

BlazkowiczОткуда вы знаете как она устроена?
автор сказал
...
Рейтинг: 0 / 0
RandomAccessFile
    #38405983
sharmanka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
суть в том, что при rw как мне кажется, никуда кроме как в конец, запистаь не получится
...
Рейтинг: 0 / 0
RandomAccessFile
    #38405989
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sharmankaсуть в том, что при rw как мне кажется, никуда кроме как в конец, запистаь не получится
Вам "кажется"? Других объективных предпосылок нет? Запись с "добавлением" не путаете?
...
Рейтинг: 0 / 0
RandomAccessFile
    #38405992
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczЗапись с "добавлением" не путаете?
Со "вставкой" то есть.
...
Рейтинг: 0 / 0
RandomAccessFile
    #38406002
jdroid
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
писать в файл одновременно невозможно (особенности устройства жесткого диска)
если нужна производительность потоков на запись, сервис копирует сообщения себе в очередь и отдает управление потоку, а фоновым потоком пишет из очереди в файл.
...
Рейтинг: 0 / 0
RandomAccessFile
    #38406017
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jdroidписать в файл одновременно невозможно (особенности устройства жесткого диска)
А кто сказал что файловая система на жестком диске?

jdroidесли нужна производительность потоков на запись, сервис копирует сообщения себе в очередь и отдает управление потоку, а фоновым потоком пишет из очереди в файл.
Не понятно чего автор темы желает. HDD и SSD можно легко полностью нагрузить одним единственным потоком.
...
Рейтинг: 0 / 0
RandomAccessFile
    #38406031
jdroid
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz100% есть готовое или 100% можно реализовать?
готовое

BlazkowiczОткуда вы знаете как она устроена?
автор сказал[/quot]

BlazkowiczА кто сказал что файловая система на жестком диске?

опишите, плиз, архитектуру системы вашего автора
...
Рейтинг: 0 / 0
RandomAccessFile
    #38406041
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sharmankaЭто не уточняется, я думаю можно писать в любое место, главное чтобы предыдущие записи не затирались.

Это уже будет нетранзакционная база данных. Что такое "предыдущие записи". Откуда поток может знать что кто-то уже что-то написал?

sharmankaавтор сказал
То есть он 100% прав. И вы 100% правильно поняли что он имел ввиду. А мы тут все вас обманываем?
...
Рейтинг: 0 / 0
RandomAccessFile
    #38406049
sharmanka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczBlazkowiczЗапись с "добавлением" не путаете?
Со "вставкой" то есть.
Хорошо, пусть будет вставка. Главное чтобы уже записанное не терялось и запись шла параллельно. То есть если есть 5 нитей, каждая из которых должна записать 200 тысяч байт, то чтобы итоговый файл вышел размером в миллион байт.


Появилась мысль ставить указатель в каждой нити пропуская N байт от начала. Тогда первая нить будет писать с нулевой позиции и до N-той, вторая с N+1 и до 2N и т.д. Тогда сложность в том, чтобы определить в какая по счету эта нить (чтобы пропустить определнное количество позиций). Что скажите по этому поводу?
...
Рейтинг: 0 / 0
RandomAccessFile
    #38406052
sharmanka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczЭто уже будет нетранзакционная база данных. Что такое "предыдущие записи". Откуда поток может знать что кто-то уже что-то написал?
Наверное вызвав метод raf.length() и сравнив его с каким-то "предыдущим" значением.
...
Рейтинг: 0 / 0
RandomAccessFile
    #38406062
jdroid
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
sharmankaBlazkowiczпропущено...

Со "вставкой" то есть.
Хорошо, пусть будет вставка. Главное чтобы уже записанное не терялось и запись шла параллельно. То есть если есть 5 нитей, каждая из которых должна записать 200 тысяч байт, то чтобы итоговый файл вышел размером в миллион байт.


Появилась мысль ставить указатель в каждой нити пропуская N байт от начала. Тогда первая нить будет писать с нулевой позиции и до N-той, вторая с N+1 и до 2N и т.д. Тогда сложность в том, чтобы определить в какая по счету эта нить (чтобы пропустить определнное количество позиций). Что скажите по этому поводу?

используйте log4j, там все уже реализовано или базу данных и транзакции в качестве бонуса, зачем изобретать велосипед
...
Рейтинг: 0 / 0
RandomAccessFile
    #38406066
sharmanka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
jdroidиспользуйте log4j, там все уже реализовано или базу данных и транзакции в качестве бонуса, зачем изобретать велосипед
хочу разобраться, поэтому нужен свой :)
...
Рейтинг: 0 / 0
RandomAccessFile
    #38406070
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sharmankaХорошо, пусть будет вставка. Главное чтобы уже записанное не терялось и запись шла параллельно. То есть если есть 5 нитей, каждая из которых должна записать 200 тысяч байт, то чтобы итоговый файл вышел размером в миллион байт.
Появилась мысль ставить указатель в каждой нити пропуская N байт от начала. Тогда первая нить будет писать с нулевой позиции и до N-той, вторая с N+1 и до 2N и т.д. Тогда сложность в том, чтобы определить в какая по счету эта нить (чтобы пропустить определнное количество позиций). Что скажите по этому поводу?
Ну, так я это и предлагал выше - завести потокобезопасный счетчик конца файла для вычисления позиции записи каждого потока.
Но какой в этом грандиозный смысл, если код тупо усложняется, а производительность диска никак не увеличивается? А в случае HDD даже уменьшается.
...
Рейтинг: 0 / 0
RandomAccessFile
    #38406071
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sharmankaхочу разобраться, поэтому нужен свой :)
Уже все разжевали подробно чтобы разобратся.
...
Рейтинг: 0 / 0
RandomAccessFile
    #38406080
sharmanka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczНу, так я это и предлагал выше - завести потокобезопасный счетчик конца файла для вычисления позиции записи каждого потока.
Но какой в этом грандиозный смысл, если код тупо усложняется, а производительность диска никак не увеличивается? А в случае HDD даже уменьшается.
Давайте считать, что у меня академический интерес :)

Вопрос по этому счетчику - как, куда, каким образом?
...
Рейтинг: 0 / 0
RandomAccessFile
    #38406082
jdroid
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
sharmankajdroidиспользуйте log4j, там все уже реализовано или базу данных и транзакции в качестве бонуса, зачем изобретать велосипед
хочу разобраться, поэтому нужен свой :)
лисапет только на картинке просто устроен, а когда начинаеш его собирать самостоятельно всплывает огромная масса нюансов
кстати log4j опенсорсный, он не за один день писался, там можно посмотреть как все должно правильно работать и понять стоит ли писать свой :-)
...
Рейтинг: 0 / 0
RandomAccessFile
    #38406084
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sharmankaДавайте считать, что у меня академический интерес :)

Дык с постановкой задачи определитесь. "Чтобы не перезатиралось" это что-то очень сумбурное и расплывчатое.
Конечная цель какая? Написать тест убедится что прирост производительности отсутствует?
Какого размера блоки записываются за одну операцию одним потоком?
Пишем только в конец или в любую позицию?

sharmankaВопрос по этому счетчику - как, куда, каким образом?

14877167
...
Рейтинг: 0 / 0
RandomAccessFile
    #38406087
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jdroid он не за один день писался, там можно посмотреть как все должно правильно работать и понять стоит ли писать свой :-)
AFAIK там очередь и однопоточная запись в файл. Так ведь?
...
Рейтинг: 0 / 0
RandomAccessFile
    #38406106
jdroid
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowiczjdroid он не за один день писался, там можно посмотреть как все должно правильно работать и понять стоит ли писать свой :-)
AFAIK там очередь и однопоточная запись в файл. Так ведь?
давно там не лазил, но вряд-ли за это время придумали что-то революционное
...
Рейтинг: 0 / 0
RandomAccessFile
    #38406196
sharmanka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем спасибо, получилось по способу, который я описывал выше.

P.S.:
Если кому-то интересно, то на этапе, когда конечный размер файла известен, а запись еще не началась создаем пустой файл и назначаем ему длину методом setLength. В нитях же, в зависимости от номера текущей нити пропускаем (номер) * (количество, которое должна записать нить) байт. На выходе имеем запись несколькими нитями одновременно в один файл без всяких локов на файл, счетчиков, и что самое важное - без затираний. Профит.
...
Рейтинг: 0 / 0
RandomAccessFile
    #38406205
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sharmankaто на этапе, когда конечный размер файла известен, а запись еще не началась
Гениально. А если размер файла не известен до записи?
...
Рейтинг: 0 / 0
RandomAccessFile
    #38406207
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Покажите код, если не сложно.
...
Рейтинг: 0 / 0
RandomAccessFile
    #38406240
sharmanka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczГениально. А если размер файла не известен до записи?
Не знаю. Как вариант - сбрасывать в какой-то кеш, обсчитывать длину и по накатанной.




cdtyjvПокажите код, если не сложно.
Да, конечно. Убрал то, что не относится к теме:
Основной файл
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
	    RandomAccessFile raf = null;
        raf = new RandomAccessFile("1.txt", "rw");
        raf.setLength(length);
        raf.close();
        
        ExecutorService exec = Executors.newFixedThreadPool(num);
        for (Integer i = 1; i <= num; i++) {
            bt.setName(i.toString());
            Future f1 = exec.submit(bt);
            lst.add(f1);
			}



Метод ран:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
    public void run() {
       RandomAccessFile raf = null;
       
        try {
            raf = new RandomAccessFile("1.txt", "rw");
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
        String tname = MyThread.currentThread().getName();
        tname = tname.substring(14);
        System.out.printf("#%s trying to write % d bytes\n",tname, Main.bytenum);
        
        try {
            Integer skip = Main.bytenum * (Integer.parseInt(tname)-1);
            int num = raf.skipBytes(skip);
            
            System.out.printf("#%s skipped %d bytes\n",tname, num);
            for (int i = 0; i < Main.bytenum; i++) {
                raf.write(Integer.parseInt(tname));
			}
			raf.close();
		}
	}
...
Рейтинг: 0 / 0
RandomAccessFile
    #38406523
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Слишком узкоспециализированный код. Нормально подходит только для случаев, когда потоки пишут данные одинаковой длины. Плюс общее количество этих данных должно быть известно заранее.
В первом вашем сообщении постановка задачи была более общей, и данные вариант кода ее не решает.
...
Рейтинг: 0 / 0
RandomAccessFile
    #38406873
jdroid
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
sharmankaВсем спасибо, получилось по способу, который я описывал выше.

P.S.:
Если кому-то интересно, то на этапе, когда конечный размер файла известен, а запись еще не началась создаем пустой файл и назначаем ему длину методом setLength. В нитях же, в зависимости от номера текущей нити пропускаем (номер) * (количество, которое должна записать нить) байт. На выходе имеем запись несколькими нитями одновременно в один файл без всяких локов на файл, счетчиков, и что самое важное - без затираний. Профит.

как вариант сферического коня в вакууме для решения абстрактных задач программирования решение вполне достойное
а если приложение должно работать хотя бы год без перезагрузки какой размер файла резервировать?
...
Рейтинг: 0 / 0
RandomAccessFile
    #38406888
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjvСлишком узкоспециализированный код. Нормально подходит только для случаев, когда потоки пишут данные одинаковой длины. Плюс общее количество этих данных должно быть известно заранее.
В первом вашем сообщении постановка задачи была более общей, и данные вариант кода ее не решает.
Та это постоянно такое. Сначала задаётся общий вопрос. На него даётся масса ответов. Затем следует ответ в стиле, "никто не смог помочь, но я молодец нашел решение для своего частного случая".
...
Рейтинг: 0 / 0
RandomAccessFile
    #38406917
jdroid
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
sharmankaна этапе, когда конечный размер файла известен, а запись еще не началась создаем пустой файл и назначаем ему длину методом setLength.

у меня всего два потока, причем точно знаю что первый запишет в файл 20 терабайт, а второй всего 10 байт. что делать если работа планировщика потоков недетерминирована и отличается в зависимости от реализации JVM а я не хочу резервировать 20 терабайт для записи 10 байт.
...
Рейтинг: 0 / 0
37 сообщений из 37, показаны все 2 страниц
Форумы / Java [игнор отключен] [закрыт для гостей] / RandomAccessFile
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]