Вставка текста в существующий файл через Java
Я хотел бы создать простую программу (в Java), которая редактирует текстовые файлы - особенно тот, который выполняет вставку произвольных фрагментов текста в случайные позиции в текстовом файле. Эта функция является частью более крупной программы, которую я сейчас пишу.
Считывая описание java.util.RandomAccessFile, кажется, что любые операции записи, выполненные в середине файла, фактически перезаписывают выходящий контент. Это побочный эффект, который я хотел бы избежать (если возможно).
Есть ли простой способ достичь этого?
Спасибо заранее.
Ответы
Ответ 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 в файле. поэтому теперь файл содержит как существующий, так и новый текст.