Существует ли способ предварительно ожидать строку в Файл в Java, не создавая временный файл, и пишущий необходимое содержание в него?
Нет, это невозможно сделать БЕЗОПАСНО на Java.
Ни одна реализация файловой системы ни в одной из основных операционных систем не поддерживает такого рода вещи, и вы не найдете эту функцию поддерживаемой ни в одном из основных языков программирования.
Реальные файловые системы реализованы на устройствах, которые хранят данные в виде «блоков» фиксированного размера. Невозможно реализовать модель файловой системы, в которой вы можете вставлять байты в середину файла без значительного замедления ввода-вывода файла, потери дискового пространства или и того, и другого.
Решения, предполагающие перезапись файла на месте, по своей сути небезопасны. Если ваше приложение будет остановлено или питание отключится в середине процесса добавления / перезаписи, вы, вероятно, потеряете данные. Я бы НЕ рекомендовал использовать этот подход на практике.
Используйте временный файл. Так безопаснее.
Есть способ, он включает в себя перезапись всего файла (но не временного файла). Как уже упоминалось, ни одна файловая система не поддерживает добавление содержимого к файлу. Вот пример кода, который использует 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);
}
}
Вы можете сохранить содержимое файла в строке и добавить желаемую строку к началу с помощью StringBuilder-Object. Вам просто нужно сначала поставить желаемую строку, а затем добавить строку file-content-String.
Никаких дополнительных временных файлов не требуется.
Нет. Нет операций "внутрифайлового сдвига", только чтение и запись дискретных размеров.
Это можно было бы сделать, прочитав кусок файла одинаковой длины к тому, что вы хотите добавить, записывая новый контент вместо него, читая последующий фрагмент и заменяя его тем, что вы читали раньше, и так далее, продвигаясь вниз до конца файла.
Однако не делайте этого, потому что если что-то остановится (нехватка памяти, отключение питания, вызов несанкционированного потока System.exit
) в середине этого процесса, данные будут потеряны. Вместо этого используйте временный файл.