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

Подготовить строки к файлу на Java

Есть ли способ добавить строку к файлу в Java, не создавая временный файл и записывая в него необходимый контент?

4b9b3361

Ответ 1

Нет, в Java нет возможности сделать это БЕСПЛАТНО.

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

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


Решения, связанные с переписыванием файла на месте, по своей сути являются небезопасными. Если ваше приложение убито или сила умирает в середине процесса prepend/rewrite, вы, вероятно, потеряете данные. Я бы не рекомендовал использовать этот подход на практике.

Использовать временный файл. Это безопаснее.

Ответ 2

Есть способ, он включает в себя переписывание всего файла (но без временного файла). Как уже упоминалось, никакая файловая система не поддерживает добавление содержимого в файл. Вот пример кода, который использует RandomAccessFile для записи и чтения содержимого при сохранении некоторого содержимого в памяти:

public static void main(final String args[]) throws Exception {
    File f = File.createTempFile(Main.class.getName(), "tmp");
    f.deleteOnExit();

    System.out.println(f.getPath());

    // put some dummy content into our file
    BufferedWriter w = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f)));
    for (int i = 0; i < 1000; i++) {
        w.write(UUID.randomUUID().toString());
        w.write('\n');
    }
    w.flush();
    w.close();

            // append "some uuids" to our file
    int bufLength = 4096;
    byte[] appendBuf = "some uuids\n".getBytes();
    byte[] writeBuf = appendBuf;
    byte[] readBuf = new byte[bufLength];

    int writeBytes = writeBuf.length;

    RandomAccessFile rw = new RandomAccessFile(f, "rw");
    int read = 0;
    int write = 0;

    while (true) {
                    // seek to read position and read content into read buffer
        rw.seek(read);
        int bytesRead = rw.read(readBuf, 0, readBuf.length);

                    // seek to write position and write content from write buffer
        rw.seek(write);
        rw.write(writeBuf, 0, writeBytes);

                    // no bytes read - end of file reached
        if (bytesRead < 0) {
                            // end of
            break;
        }

                    // update seek positions for write and read
        read += bytesRead;
        write += writeBytes;
        writeBytes = bytesRead;

                    // reuse buffer, create new one to replace (short) append buf
        byte[] nextWrite = writeBuf == appendBuf ? new byte[bufLength] : writeBuf;
        writeBuf = readBuf;
        readBuf = nextWrite;
    };

    rw.close();

            // now show the content of our file
    BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(f)));

    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
}

Ответ 3

Нет. Нет операций "внутри файла", только чтение и запись дискретных размеров.

Ответ 4

Да, есть. Просто прочитайте файл полностью в памяти Java, а затем полностью запишите его в тот же файл с новыми добавленными строками. Это, однако, не так эффективно и небезопасно для памяти (больше риска потерять данные во время сбоя), поэтому я бы действительно подумал о том, чтобы сохранить временный файловый подход. Чтобы ускорить работу, вы можете просто rename после закрытия, чтобы вам не нужно было передавать данные вперед и назад для два раза.

Ответ 5

Вы можете сохранить содержимое файла в String и добавить нужную строку с помощью StringBuilder-Object. Вам просто нужно сначала поместить нужную строку, а затем добавить файл-контент-String.
Не требуется дополнительный временный файл.

Ответ 6

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

Однако не делайте этого, потому что, если в середине этого процесса произойдет что-либо (из-за нехватки памяти, перебой питания, вызов изгоев потока System.exit), данные будут потеряны. Вместо этого используйте временный файл.

Ответ 7

private static void addPreAppnedText (File fileName) {

FileOutputStream fileOutputStream = null;

    BufferedReader br = null;
    FileReader fr = null;
    String newFileName = fileName.getAbsolutePath() + "@";

    try {

        fileOutputStream = new FileOutputStream(newFileName);
        fileOutputStream.write("preappendTextDataHere".getBytes());

        fr = new FileReader(fileName);
        br = new BufferedReader(fr);

        String sCurrentLine;

        while ((sCurrentLine = br.readLine()) != null) {
            fileOutputStream.write(("\n"+sCurrentLine).getBytes());

        }
        fileOutputStream.flush();


    } catch (IOException e) {

        e.printStackTrace();

    } finally {
        try {
            fileOutputStream.close();
            if (br != null)
                br.close();

            if (fr != null)
                fr.close();


            new File(newFileName).renameTo(new File(newFileName.replace("@", "")));


        } catch (IOException ex) {

            ex.printStackTrace();

        }

    }

}