Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prepend lines to file in Java

Tags:

Is there a way to prepend a line to the File in Java, without creating a temporary file, and writing the needed content to it?

like image 684
George Avatar asked Mar 29 '10 12:03

George


People also ask

How do you append a line in an existing file in Java?

Instantiate the BufferedWriter class. By passing the FileWriter object as an argument to its constructor. Write data to the file using the write() method.

How do I append a file with FileOutputStream?

Using FileOutputStream FileOutputStream is meant for writing streams of raw bytes such as image data. For writing streams of characters, consider using FileWriter . To append content to an existing file, open FileOutputStream in append mode by passing the second argument as true .

How do you append one file to another in Java?

The write() method takes the path of the given file, the text to the written, and how the file should be open for writing. In our case, we used APPEND option for writing. Since the write() method may return an IOException , we use a try-catch block to catch the exception properly.

Does FileWriter append?

FileWriter takes an optional second parameter: append . If set to true, then the data will be written to the end of the file. This example appends data to a file with FileWriter .


2 Answers

No, there is no way to do that SAFELY in Java. (Or AFAIK, any other programming language.)

No filesystem implementation in any mainstream operating system supports this kind of thing, and you won't find this feature supported in any mainstream programming languages.

Real world file systems are implemented on devices that store data as fixed sized "blocks". It is not possible to implement a file system model where you can insert bytes into the middle of a file without significantly slowing down file I/O, wasting disk space or both.


The solutions that involve an in-place rewrite of the file are inherently unsafe. If your application is killed or the power dies in the middle of the prepend / rewrite process, you are likely to lose data. I would NOT recommend using that approach in practice.

Use a temporary file and renaming. It is safer.

like image 105
Stephen C Avatar answered Oct 27 '22 12:10

Stephen C


There is a way, it involves rewriting the whole file though (but no temporary file). As others mentioned, no file system supports prepending content to a file. Here is some sample code that uses a RandomAccessFile to write and read content while keeping some content buffered in memory:

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);     } } 
like image 42
sfussenegger Avatar answered Oct 27 '22 12:10

sfussenegger