Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use FileChannel to append one file's contents on to the end of another file?

Tags:

java

File a.txt looks like:

ABC

File d.txt looks like:

DEF

I'm trying to take "DEF" and append it to "ABC" so a.txt looks like

ABC
DEF

The methods I've tried always completely overwrite the first entry so I always end up with:

DEF

Here are the two methods I've tried:

FileChannel src = new FileInputStream(dFilePath).getChannel(); 
FileChannel dest = new FileOutputStream(aFilePath).getChannel();

src.transferTo(dest.size(), src.size(), dest);

...and I've tried

FileChannel src = new FileInputStream(dFilePath).getChannel(); 
FileChannel dest = new FileOutputStream(aFilePath).getChannel();

dest.transferFrom(src, dest.size(), src.size());

The API is unclear about the transferTo and transferFrom param descriptions here:

http://docs.oracle.com/javase/7/docs/api/java/nio/channels/FileChannel.html#transferTo(long, long, java.nio.channels.WritableByteChannel)

Thanks for any ideas.

like image 840
Joe Essey Avatar asked Nov 21 '13 20:11

Joe Essey


3 Answers

This is old but the override occurs because of the mode that you open your file output stream. For anyone that needs this, try

FileChannel src = new FileInputStream(dFilePath).getChannel(); 
FileChannel dest = new FileOutputStream(aFilePath, true).getChannel();  //<---second argument for FileOutputStream
dest.position( dest.size() );
src.transferTo(0, src.size(), dest);
like image 118
Alkis Kalogeris Avatar answered Oct 19 '22 04:10

Alkis Kalogeris


Move position of destination channel to the end:

FileChannel src = new FileInputStream(dFilePath).getChannel(); 
FileChannel dest = new FileOutputStream(aFilePath).getChannel();
dest.position( dest.size() );
src.transferTo(0, src.size(), dest);
like image 38
Nicolai Avatar answered Oct 19 '22 02:10

Nicolai


pure nio solution

FileChannel src = FileChannel.open(Paths.get(srcFilePath), StandardOpenOption.READ);
FileChannel dest = FileChannel.open(Paths.get(destFilePath), StandardOpenOption.APPEND); // if file may not exist, should plus StandardOpenOption.CREATE
long bufferSize = 8 * 1024;
long pos = 0;
long count;
long size = src.size();
while (pos < size) {
    count = size - pos > bufferSize ? bufferSize : size - pos;
    pos += src.transferTo(pos, count, dest); // transferFrom doesn't work
}
// do close
src.close();
dest.close();

However, I still have a question: Why transferFrom doesn't work here?

like image 23
kissrain Avatar answered Oct 19 '22 03:10

kissrain