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

Вставка текста в существующий файл через Java

Я хотел бы создать простую программу (в Java), которая редактирует текстовые файлы - особенно тот, который выполняет вставку произвольных фрагментов текста в случайные позиции в текстовом файле. Эта функция является частью более крупной программы, которую я сейчас пишу.

Считывая описание java.util.RandomAccessFile, кажется, что любые операции записи, выполненные в середине файла, фактически перезаписывают выходящий контент. Это побочный эффект, который я хотел бы избежать (если возможно).

Есть ли простой способ достичь этого?

Спасибо заранее.

4b9b3361

Ответ 1

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

Вот пример (игнорируя исключения и некоторые другие вещи):

public void insert(String filename, long offset, byte[] content) {
  RandomAccessFile r = new RandomAccessFile(new File(filename), "rw");
  RandomAccessFile rtemp = new RandomAccessFile(new File(filename + "~"), "rw");
  long fileSize = r.length();
  FileChannel sourceChannel = r.getChannel();
  FileChannel targetChannel = rtemp.getChannel();
  sourceChannel.transferTo(offset, (fileSize - offset), targetChannel);
  sourceChannel.truncate(offset);
  r.seek(offset);
  r.write(content);
  long newOffset = r.getFilePointer();
  targetChannel.position(0L);
  sourceChannel.transferFrom(targetChannel, newOffset, (fileSize - offset));
  sourceChannel.close();
  targetChannel.close();
}

Ответ 2

Ну, нет, я не верю, что есть способ избежать перезаписи существующего контента с помощью одного стандартного вызова Java IO API.

Если файлы не слишком большие, просто прочитайте весь файл в ArrayList (запись в строке) и перепишите записи или вставьте новые записи для новых строк.

Затем перезапишите существующий файл новым контентом или переместите существующий файл в резервную копию и напишите новый файл.

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

Другим методом будет чтение символов из существующего файла при записи в отредактированный файл и редактирование потока по мере его чтения.

Ответ 3

Вы можете использовать следующий код:

BufferedReader reader = null;
BufferedWriter writer = null;
ArrayList list = new ArrayList();

try {
    reader = new BufferedReader(new FileReader(fileName));
    String tmp;
    while ((tmp = reader.readLine()) != null)
        list.add(tmp);
    OUtil.closeReader(reader);

    list.add(0, "Start Text");
    list.add("End Text");

    writer = new BufferedWriter(new FileWriter(fileName));
    for (int i = 0; i < list.size(); i++)
        writer.write(list.get(i) + "\r\n");
} catch (Exception e) {
    e.printStackTrace();
} finally {
    OUtil.closeReader(reader);
    OUtil.closeWriter(writer);
}

Ответ 4

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

Это работает в C. Никогда не пробовал это на Java.

Еще один способ, который я только что решил сделать, но со случайным доступом к файлам.

  • Ищите до конца - 1 МБ
  • Читать 1 МБ
  • Напишите это в исходное положение + размер зазора.
  • Повторите для каждого предыдущего 1 Мбайта, работающего в начале файла.
  • Остановитесь, когда вы достигнете желаемой позиции зазора.

Используйте более крупный размер буфера для повышения производительности.

Ответ 5

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

Этот пример сосредоточен на вставке одной строки в существующий файл, но, возможно, вам может быть полезен.

Ответ 6

Я не знаю, есть ли способ сделать это прямо, иначе

  • прочитайте начало файла и запишите его в целевой
  • напишите свой новый текст в цель
  • прочитайте остальную часть файла и запишите его в целевую.

О цели: вы можете создать новое содержимое файла в памяти и затем перезаписать старое содержимое файла, если обрабатываемые файлы не так велики. Или вы можете записать результат во временный файл.

Вещь, вероятно, будет проще всего делать с потоками, RandomAccessFile, похоже, не предназначен для вставки в середине (afaik). Если вам нужно, tutorial

Ответ 7

Если это текстовый файл,, Прочитайте существующий файл в StringBuffer и добавьте новый контент в тот же StringBuffer, и теперь вы можете написать файл SrtingBuffer в файле. поэтому теперь файл содержит как существующий, так и новый текст.