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

Измените .txt файл в Java

У меня есть текстовый файл, который я хочу редактировать с помощью Java. Он имеет много тысяч линий. Я в основном хочу перебирать строки и изменять/редактировать/удалять текст. Это должно произойти довольно часто.

Из решений, которые я видел на других сайтах, общий подход выглядит следующим образом:

  • Откройте существующий файл с помощью BufferedReader
  • Прочитайте каждую строку, внесите изменения в каждую строку и добавьте ее в StringBuilder
  • После того, как весь текст будет прочитан и изменен, напишите содержимое StringBuilder в новый файл
  • Заменить старый файл новым файлом

Это решение кажется мне немного "взломанным", особенно если у меня есть тысячи строк в текстовом файле.

Кто-нибудь знает о лучшем решении?

4b9b3361

Ответ 1

Я недавно не делал этого в Java, но запись всего файла в память кажется плохой идеей.

Лучшая идея, которую я могу придумать, - это открыть временный файл в режиме записи одновременно, а для каждой строки - прочитать его, при необходимости изменить, а затем записать во временный файл. В конце удалите оригинал и переименуйте временный файл.

Если у вас есть права на изменение в файловой системе, возможно, вы также имеете права на удаление и переименование.

Ответ 2

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

Вы можете использовать apache IOUtils, который имеет следующий метод.

public static String readFile(String filename) throws IOException {
    File file = new File(filename);
    int len = (int) file.length();
    byte[] bytes = new byte[len];
    FileInputStream fis = null;
    try {
        fis = new FileInputStream(file);
        assert len == fis.read(bytes);
    } catch (IOException e) {
        close(fis);
        throw e;
    }
    return new String(bytes, "UTF-8");
}

public static void writeFile(String filename, String text) throws IOException {
    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream(filename);
        fos.write(text.getBytes("UTF-8"));
    } catch (IOException e) {
        close(fos);
        throw e;
    }
}

public static void close(Closeable closeable) {
    try {
        closeable.close();
    } catch(IOException ignored) {
    }
}

Ответ 3

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

Ответ 4

Нет причин для буферизации всего файла.

Просто напишите каждую строку, когда вы ее прочитали, вставьте строки, когда это необходимо, удалите строки, когда это необходимо, замените строки, когда это необходимо.

По сути, вам не придется обновлять файл, особенно если это текстовый файл.

Ответ 5

Каковы данные? Вы управляете форматом файла?

Если файл содержит пары имя/значение (или аналогичные), вам может быть повезло с Properties или, возможно, что-то использует драйвер JDBC с плоским файлом.

В качестве альтернативы вы считаете, что не так часто записываете данные? Работа с копией файла в памяти должна быть относительно тривиальной. Если нет внешних ресурсов, которые нуждаются в обновлении файла в реальном времени, тогда нет необходимости переходить на диск каждый раз, когда вы хотите внести изменения. Вы можете запустить запланированную задачу для записи периодических обновлений на диск, если вас беспокоит резервное копирование данных.

Ответ 6

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

Ответ 7

Не можете ли вы использовать регулярные выражения, если знаете, что хотите изменить? Jakarta Regexp должен, вероятно, сделать трюк.

Ответ 9

Несмотря на то, что этот вопрос был опубликован, я думаю, что это хорошо, чтобы ответить на этот вопрос. Я считаю, что наилучшим подходом является использование пакета FileChannel из java.nio.channels в этом сценарии. Но это, только если вам нужно иметь хорошую производительность! Вам нужно будет получить FileChannel через RandomAccessFile, например:

java.nio.channels.FileChannel channel = new java.io.RandomAccessFile("/my/fyle/path", "rw").getChannel();

После этого вам нужно создать a ByteBuffer, где вы будете читать из FileChannel.

это выглядит примерно так:


java.nio.ByteBuffer inBuffer = java.nio.ByteBuffer.allocate(100);
int pos = 0;
int aux = 0;
StringBuilder sb = new StringBuilder();

while (pos != -1) {

    aux = channel.read(inBuffer, pos);
    pos = (aux != -1) ? pos + aux : -1;

    b = inBuffer.array();
    sb.delete(0, sb.length());

    for (int i = 0; i < b.length; ++i) {

         sb.append((char)b[i]);

    }

    //here you can do your stuff on sb

    inBuffer = ByteBuffer.allocate(100);

}

Надеюсь, что мой ответ вам поможет!

Ответ 10

Вы можете использовать RandomAccessFile в Java для изменения файла при одном условии: Размер каждой строки должен быть исправлен иначе, когда новая строка будет записана обратно, она может переопределить строку в следующей строке.

Поэтому в моем примере я устанавливаю длину строки как 100 и заполняю строку пробела при создании файла и записи обратно в файл.

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

public class RandomAccessFileUtil {
public static final long RECORD_LENGTH = 100;
public static final String EMPTY_STRING = " ";
public static final String CRLF = "\n";

public static final String PATHNAME = "/home/mjiang/JM/mahtew.txt";

/**
 *  one two three
    Text to be appended with
    five six seven
    eight nine ten
 * 
 * 
 * @param args
 * @throws IOException
 */
public static void main(String[] args) throws IOException
{
    String starPrefix = "Text to be appended with";
    String replacedString = "new text has been appended";

    RandomAccessFile file = new RandomAccessFile(new File(PATHNAME), "rw");

    String line = "";
    while((line = file.readLine()) != null)
    {
        if(line.startsWith(starPrefix))
        {
            file.seek(file.getFilePointer() - RECORD_LENGTH - 1);
            file.writeBytes(replacedString);
        }

    }
}

public static void createFile() throws IOException
{
    RandomAccessFile file = new RandomAccessFile(new File(PATHNAME), "rw");

    String line1 = "one two three";
    String line2 = "Text to be appended with";
    String line3 = "five six seven";
    String line4 = "eight nine ten";

    file.writeBytes(paddingRight(line1));
    file.writeBytes(CRLF);
    file.writeBytes(paddingRight(line2));
    file.writeBytes(CRLF);
    file.writeBytes(paddingRight(line3));
    file.writeBytes(CRLF);
    file.writeBytes(paddingRight(line4));
    file.writeBytes(CRLF);

    file.close();

    System.out.println(String.format("File is created in [%s]", PATHNAME));
}

public static String paddingRight(String source)
{
    StringBuilder result = new StringBuilder(100);
    if(source != null)
    {
        result.append(source);
        for (int i = 0; i < RECORD_LENGTH - source.length(); i++)
        {
            result.append(EMPTY_STRING);
        }
    }

    return result.toString();
}

}

Ответ 11

Вы можете изменить txt файл на java, сохранив при нажатии "Сохранить как" и сохраните расширение *.java.