public void copyFile ( File src , File dst , boolean hardlink ) throws IOException { if ( src == null || dst == null ) { throw new IOException ( "src/dst file is null" ) ; } try { if ( hardlink && shouldHardLinkBlockCopy ) { // Remove destination before hard linking, since this file might already // exist and a hardlink would fail as a result. if ( dst . exists ( ) ) { if ( ! dst . delete ( ) ) { throw new IOException ( "Deletion of file : " + dst + " failed" ) ; } } NativeIO . link ( src , dst ) ; DataNode . LOG . info ( "Hard Link Created from : " + src + " to " + dst ) ; return ; } } catch ( IOException e ) { DataNode . LOG . warn ( "Hard link failed from : " + src + " to " + dst + " continuing with regular file copy" ) ; } FileChannel input = null ; FileChannel output = null ; try { // This improves copying performance a lot, it uses native buffers // for copying. input = new FileInputStream ( src ) . getChannel ( ) ; output = new FileOutputStream ( dst ) . getChannel ( ) ; if ( input == null || output == null ) { throw new IOException ( "Could not create file channels for src : " + src + " dst : " + dst ) ; } long bytesLeft = input . size ( ) ; long position = 0 ; while ( bytesLeft > 0 ) { long bytesWritten = output . transferFrom ( input , position , bytesLeft ) ; bytesLeft -= bytesWritten ; position += bytesWritten ; } if ( datanode . syncOnClose ) { output . force ( true ) ; } } finally { if ( input != null ) { input . close ( ) ; } if ( output != null ) { output . close ( ) ; } } }
Copies a file as fast as possible . Tries to do a hardlink instead of a copy if the hardlink parameter is specified .