Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > замена слов в текстовом файле


Автор: Pawl 30.9.2011, 11:11
Доброго времени суток, Господа!
Похожие вопросы тут обсуждались, но ответа для себя я так и не нашёл.
Так вот, есть текстовый файл. Можно ли прямо в нем заменить определенное слово другим словом? Если использовать временный файл, то больших проблем тут нет, а вот если работать только с данным файлом? Я пытаюсь через RandomAccessFile, но пока не получается. Может, чего полезного посоветуете?
Спасибо!

Автор: Samotnik 30.9.2011, 11:15
Pawl, Считай файл в буфер, измени слова, выведи результат из буфера в файл.

Автор: LSD 30.9.2011, 11:35
Если слово такое же по длине(в байтах) , то проблем нет. Просто переписываешь это место.

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

Автор: Pawl 30.9.2011, 13:24
Цитата(LSD @  30.9.2011,  11:35 Найти цитируемый пост)
Если слово такое же по длине(в байтах) , то проблем нет. Просто переписываешь это место.Если слово короче, то записываешь слово начиная с первой позиции старого слова, затем берешь байт следующий за последним байтом старого слова и пишешь в позицию следующую за новым словом. И так далее до конца файла. После чего соответственно уменьшаешь его длину. Плюс это все желательно делать блоками, а не побайтово.Если слово длиннее, то вначале увеличиваешь длину файла, и смещаешь данные в конец файла, а затем уже пишешь новое слово.

А можно примерчик, пожалуйста? smile

Добавлено через 2 минуты и 19 секунд
Цитата(Samotnik @  30.9.2011,  11:15 Найти цитируемый пост)
awl, Считай файл в буфер, измени слова, выведи результат из буфера в файл.

Спасибо за вариант, но это, по сути та же запись во временный файл, который находится в буфере, а хотелось бы работать НЕПОСРЕДСТВЕННО с файлом!

Автор: LSD 30.9.2011, 16:28
Код

    private static void move(final FileChannel file, final int startPosition, final int delta) throws IOException {
        ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
        if (delta < 0) {
            long currentPosition = startPosition;
            while (currentPosition <= file.size()) {
                file.position(currentPosition);
                buffer.rewind();
                int read = file.read(buffer);
                buffer.rewind();
                buffer.limit(read);
                file.position(currentPosition + delta);
                file.write(buffer);
                currentPosition += BUFFER_SIZE;
            }
        } else if (delta > 0) {
            throw new NotImplementedException();
        }
        file.force(false);
    }

Автор: Pawl 30.9.2011, 18:52
Цитата(LSD @  30.9.2011,  16:28 Найти цитируемый пост)
код Java

Ого, спасибо! Честно, с пакетом NIO не работал, так что пока не понял, то ли это, что мне надо... Пойму - отпишусь smile 

Автор: Pawl 1.10.2011, 17:48
По поводу примера г-на LSD. Если я правильно понял, в нем в буфер считывается кусок данных из файла, затем маркер сдвигается на заданную величину и в файл записываются данные из того же буфера, т. е. тот же кусок данных. А можно ли в файле ЗАМЕНЯТЬ этот кусок на какой-то другой, задаваемый пользователем?

Автор: LSD 3.10.2011, 11:12
Этот код просто сдвигает данные в файле начиная с указанной позиции, на указанную дельту. Вызов move(channel, 3, -2) порождает такие изменения (BUFFER_SIZE = 2 для наглядности):
Код

1234567890
1454567890
1456767890
1456789890
1456789090

После чего надо вызывать:
Код

channel.truncate(сhannel.size() - 2);

и получим:
Код

14567890


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

Автор: Pawl 5.10.2011, 10:21
Цитата(LSD @  3.10.2011,  11:12 Найти цитируемый пост)
Т.е. алгоритм такой:

Спасибо, достаточно наглядно. Думаю, дальше разберусь сам.

Автор: Pawl 7.10.2011, 14:45
Да, опрометчиво закрыл тему!
с заменой слова на слово такой же или меньшей длины разобрался, а вот с этим:
Цитата(LSD @  3.10.2011,  11:12 Найти цитируемый пост)
-- увеличиваем длину файла--- смещаем байты

не очень. Можно, пожалуйста, пример, как это сделать?  smile 

Спасибо!

Автор: LSD 7.10.2011, 15:03
Увеличить длину можно с помощью RandomAccessFile.setLength() (все равно, FileChannel создавать надо через него). Алгоритм сдвига байтов в конец файла такой же как и в начало, только начинать надо с конца сдвигаемой области, а не с начала.

Автор: Pawl 7.10.2011, 16:20
Цитата(LSD @  7.10.2011,  15:03 Найти цитируемый пост)
Увеличить длину можно с помощью RandomAccessFile.setLength()

Спасибо, уже нашел http://devhead.ru/read/java-kak-vstavit-stroku-v-nachalo-fajla/ на похожий пример!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)