Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как изменить часть строк в файле? 
:(
    Опции темы
erslgoeirjh
Дата 5.5.2012, 11:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 147
Регистрация: 16.12.2005

Репутация: нет
Всего: нет



Есть текстовой файл data.txt , состоящий из 10 строк. Как изменить 9 и 10 строки в этом файле, а остальные (1--8) оставить без изменения?

PM MAIL   Вверх
LSD
Дата 5.5.2012, 11:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Смотря что подразумевается под "изменить". Если изменить это заменить символ X на Y, то можно обойтись RandomAccessFile. Если же строка в результате поменяет длину (или еще как изменится количество байт в строке), то проще создать новый файл, записать туда первые 9 строк без изменения, записать 9 и 10 измененные строки. Удалить старый файл, а новый переименовать.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Pawl
Дата 10.5.2012, 23:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: 7
Всего: 28



Цитата(LSD @  5.5.2012,  11:57 Найти цитируемый пост)
Если же строка в результате поменяет длину (или еще как изменится количество байт в строке), то проще создать новый файл, записать туда первые 9 строк без изменения, записать 9 и 10 измененные строки. Удалить старый файл, а новый переименовать.

Может, и проще, но иногда работа с одним файлом - жесткое требование заказчика.
Я делал похожую задачу, только малость сложнее. Мне надо было заменить в файле регулярное выражение определенным символом. Кстати, помогли мне это сделать тут, на форуме, а также я нашел статью с примером, как увеличивать/уменьшать размер файла. Свой код я тут приведу, Вам надо будет его только малость упростить. К примеру, я читал в буфер из файла посимвольно, в объект StringBuilder и проверял, есть ли в этом объекте искомое регулярное выражение. Если нет, читал дальше, а если да - преобразовывал StringBuilder в строку, делал в ней замену, сравнивал длину новой строки со старой, если нужно - изменял размер файла, записывал в него новую строку и читал файл дальше. Вам же можно просто считать 8 строк (хотя бы redLine'ом), а 9-ю и 10-ю последовательно сверить по длине с соответствующими новыми строками, при необходимости каждый раз изменять длину файла и писать в файл новые строки, как это сделано у меня.
Код

import java.io.RandomAccessFile;
import java.io.IOException;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.Charset;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class Replacer {

    public static void replace(String fileName, String replable, String replacer) throws IOException, IllegalArgumentException {
        Charset cs = Charset.defaultCharset();
        Pattern p = Pattern.compile(replable);
        try (RandomAccessFile r = new RandomAccessFile(fileName, "rw"); FileChannel file = r.getChannel()) {
            Mover er = new Mover(fileName, "rw");
            int i = 1;
            long currentPosition = 0, position = 0;
            StringBuilder sb = new StringBuilder();
            while (currentPosition < file.size()) {
                Matcher m = p.matcher(sb);
                /**
                 * записываем в буфер байты до тех пор, пока в строке
                 * не встретится искомое регулярное выражение
                 */
                if (!m.find()) {
                    sb.delete(0, sb.length());
                    file.position(position);
                    ByteBuffer buffer = ByteBuffer.allocate(i++);
                    int read = file.read(buffer);
                    buffer.rewind();
                    CharBuffer chbuf = cs.decode(buffer);
                    sb.append(chbuf);
                    currentPosition++;
                } else {
                    currentPosition = position;
                    String str = new String(sb);
                    sb.delete(0, sb.length());
                    String oldStr = str;
                    str = str.replaceAll(replable, replacer);
                    if (str.length() != oldStr.length()) {
                        /**
                         * если размер заменяемого выражения не совпадает с заменяющим
                         * текстом, сдвигаем байты в файле и изменяем его размер
                         */
                        er.move(str.getBytes().length - oldStr.getBytes().length, file.position());
                    }
                    /**
                     * записываем в файл изменённую строку и переводим курсор в следующую
                     * позицию для чтения
                     */
                    file.position(position);
                    file.write(getByts(str));
                    position += str.length();
                    i = 1;
                }
            }
        }
    }

    private static ByteBuffer getByts(String s) {
        ByteBuffer b = ByteBuffer.wrap(s.getBytes());
        return b;
    }

    public static void main(String[] args) {
        try {
            replace("!!!.txt", "\\d+", "I");
        } catch (IOException | IllegalArgumentException e) {
            e.printStackTrace();
        }
    }
}

Код

package chantest;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

public class Mover extends RandomAccessFile {
   /**
    * Буффер для для чтения и записи в файл
    */
   private byte[] buffer = new byte[8192];

   public Mover(String name, String mode) throws FileNotFoundException {
      super(name, mode);
   }

   public Mover(File file, String mode) throws FileNotFoundException {
      super(file, mode);
   }

   public void move(int pos, long off) throws IOException {
      long oldLength = length();
      if (off < oldLength) {
         /**
          * Если смещение меньше длины файла, т.е. вставляем как
          * бы в середину файла...
         
         /**
          * Точка начиная с которой будем двигать куски файла в конец
          * buffer.length -размер передвигаемого куска
          */
         long startChunk = oldLength - buffer.length;
         while (true) {
            /**
             * Сначала передвигаем куски равные buffer.length
             */
            if (startChunk >= off) {
               seek(startChunk);
               readFully(buffer);
               seek(startChunk + pos);
               write(buffer);
            } else {
                /**
                 * В конце обычно остается кусок меньше buffer.length
                 * соответственно читаем не весь буфер, а только часть
                 */
               seek(off);
               int chunkLength = (int)(buffer.length + startChunk - off);
               readFully(buffer, 0, chunkLength);
               /**
                * Изменяем длину файла на длину вставляемого массива
                */
               setLength(oldLength + pos);              
               seek(off + pos);
               write(buffer, 0, chunkLength);
               break;
            }
            startChunk -= buffer.length;
         }
      } else {
         /**
          * Если смещение больше длины файла,
          * ничего сохранять и перемещать ненадо, просто увеличиваем файл:
          */
         setLength(off + pos);
      }
   }
}


Добавлено через 3 минуты и 49 секунд
Странно, почему текст кода не отформатировался... Вроде, правильно код вставлял.


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
priam220
Дата 12.5.2012, 20:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 4.6.2010

Репутация: 7
Всего: 8



прочитать файл (в вашем случае можно целиком) в строку ,изменить там все как нужно, reg ex'ом например, и перезаписать:

Код

 public static void main(String[] args) throws IOException {
 BufferedWriter bw = new BufferedWriter(new FileWriter("/home/txt.txt"));
 bw.write ("text");
 bw.newLine();
 bw.flush();
 bw.close();
    }

PM MAIL   Вверх
Pawl
Дата 12.5.2012, 22:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: 7
Всего: 28



Цитата(priam220 @  12.5.2012,  20:20 Найти цитируемый пост)
прочитать файл (в вашем случае можно целиком)

Вообще да, для ДАННОГО случая - это самый простой вариант smile 


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0510 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.