Reputation: 275
I need to write something into a text file's beginning. I have a text file with content and i want write something before this content. Say i have;
Good afternoon sir,how are you today?
I'm fine,how are you?
Thanks for asking,I'm great
After modifying,I want it to be like this:
Page 1-Scene 59
25.05.2011Good afternoon sir,how are you today?
I'm fine,how are you?
Thanks for asking,I'm great
Just made up the content :) How can i modify a text file like this way?
Upvotes: 13
Views: 32025
Reputation: 533
After reading atk's answer, I came up with my own implementation:
/** Prepends the provided data to the very beginning of the file.<br>
* This functions works by overwriting the contents of the file block-by-block, first inserting the new data at the start, then
* proceeding to shift each block down until it reaches the end of the file, at which point the last 'previous' block is written.<br>
* <br>
* Note that while prepending large files will not take up any extra storage space or memory, the operation will take longer to
* complete, as it is necessary to re-write the entire file's contents once the operation has begun.
*
* @param data The data to prepend
* @param off The offset within the data to read from
* @param len The number of bytes to read within the data array
* @param file The file to prepend the data onto
* @throws IOException If an I/O error occurs while reading or writing to the file
* @author Brian_Entei */
public static final void prependBytes(byte[] data, int off, int len, File file) throws IOException {
// Insert-and-overwrite algorithm
// Could potentially optimize by setting a fixed buffer length (e.g. 4096), but will then need to update/manage how many bytes are read from the stream
final byte[] oldBuf = new byte[len];
final byte[] buf = new byte[oldBuf.length];
// Pre-load our prefix data into oldBuf
System.arraycopy(data, off, oldBuf, 0, len);
try(RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
long pos = raf.getFilePointer();// store current file pointer (index into file, should be zero)
int length, oldLength = oldBuf.length;
while((length = raf.read(buf)) != -1) {// Let's read the first buffer (or 'block') of data
raf.seek(pos);// since we've just read from the stream and the pointer has been changed, roll it back so that we can overwrite what we just read
raf.write(oldBuf, 0, oldLength);// write the previously read data in the current data's place
oldLength = length;// store the currently read data's length ...
System.arraycopy(buf, 0, oldBuf, 0, length);// ... and data for the next loop iteration ...
pos = raf.getFilePointer();// ... as well as the pointer (since we've just read from the stream, thus advancing the index)
}
raf.write(oldBuf, 0, oldLength);// (don't forget to write the last bit of data once finished!)
}
}
/** Prepends the provided data to the very beginning of the file.<br>
* This functions works by overwriting the contents of the file block-by-block, first inserting the new data at the start, then
* proceeding to shift each block down until it reaches the end of the file, at which point the last 'previous' block is written.<br>
* <br>
* Note that while prepending large files will not take up any extra storage space or memory, the operation will take longer to
* complete, as it is necessary to re-write the entire file's contents once the operation has begun.
*
* @param data The data to prepend
* @param file The file to prepend the data onto
* @throws IOException If an I/O error occurs while reading or writing to the file
* @author Brian_Entei */
public static final void prependBytes(byte[] data, File file) throws IOException {
prependBytes(data, 0, data.length, file);
}
/** Example usage of {@linkplain #prependBytes(byte[], File)}.<br>
* <br>
* This method inserts the UTF-8 BOM into the start of the target file.
*
* @param file The text file
* @throws IOException If an I/O error occurs while reading or writing to the file */
public static final void insertUTF8BOM(File file) throws IOException {
prependBytes(new byte[] {(byte) 0xEF, (byte) 0xBB, (byte) 0xBF}, file);
}
This method doesn't create any temporary files or use up a huge amount of memory, but it does do a lot of reading and writing. Things could probably be further optimized, but it works well enough for me.
Upvotes: 0
Reputation: 1
I will leave it here just in case anyone need
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try (FileInputStream fileInputStream1 = new FileInputStream(fileName1);
FileInputStream fileInputStream2 = new FileInputStream(fileName2)) {
while (fileInputStream2.available() > 0) {
byteArrayOutputStream.write(fileInputStream2.read());
}
while (fileInputStream1.available() > 0) {
byteArrayOutputStream.write(fileInputStream1.read());
}
}
try (FileOutputStream fileOutputStream = new FileOutputStream(fileName1)) {
byteArrayOutputStream.writeTo(fileOutputStream);
}
Upvotes: 0
Reputation: 3093
Just in case it will be useful for someone here is full source code of method to prepend lines to a file using Apache Commons IO library. The code does not read whole file into memory, so will work on files of any size.
public static void prependPrefix(File input, String prefix) throws IOException {
LineIterator li = FileUtils.lineIterator(input);
File tempFile = File.createTempFile("prependPrefix", ".tmp");
BufferedWriter w = new BufferedWriter(new FileWriter(tempFile));
try {
w.write(prefix);
while (li.hasNext()) {
w.write(li.next());
w.write("\n");
}
} finally {
IOUtils.closeQuietly(w);
LineIterator.closeQuietly(li);
}
FileUtils.deleteQuietly(input);
FileUtils.moveFile(tempFile, input);
}
Upvotes: 17
Reputation: 15955
This isn't a direct answer to the question, but often files are accessed via InputStreams. If this is your use case, then you can chain input streams via SequenceInputStream
to achieve the same result. E.g.
InputStream inputStream = new SequenceInputStream(new ByteArrayInputStream("my line\n".getBytes()), new FileInputStream(new File("myfile.txt")));
Upvotes: 1
Reputation: 168
As @atk suggested, java.nio.channels.SeekableByteChannel
is a good interface. But it is available from 1.7 only.
Update : If you have no issue using FileUtils then use
String fileString = FileUtils.readFileToString(file);
Upvotes: 2
Reputation: 9314
I think what you want is random access. Check out the related java tutorial. However, I don't believe you can just insert data at an arbitrary point in the file; If I recall correctly, you'd only overwrite the data. If you wanted to insert, you'd have to have your code
Upvotes: 3
Reputation: 1499880
You can't really modify it that way - file systems don't generally let you insert data in arbitrary locations - but you can:
Upvotes: 27