question: public void append ( String fileName , InputStream inputStream , long streamOffset , FTPDataTransferListener listener ) throws IllegalStateException , IOException , FTPIllegalReplyException , FTPException , FTPDataTransferException , FTPAbortedException { synchronized ( lock ) { if ( ! connected ) { throw new IllegalStateException ( "Client not connected" ) ; } if ( ! authenticated ) { throw new IllegalStateException ( "Client not authenticated" ) ; } int tp = type ; if ( tp == TYPE_AUTO ) { tp = detectType ( fileName ) ; } if ( tp == TYPE_TEXTUAL ) { communication . sendFTPCommand ( "TYPE A" ) ; } else if ( tp == TYPE_BINARY ) { communication . sendFTPCommand ( "TYPE I" ) ; } FTPReply r = communication . readFTPReply ( ) ; touchAutoNoopTimer ( ) ; if ( ! r . isSuccessCode ( ) ) { throw new FTPException ( r ) ; } boolean wasAborted = false ; FTPDataTransferConnectionProvider provider = openDataTransferChannel ( ) ; communication . sendFTPCommand ( "APPE " + fileName ) ; try { Socket dtConnection ; try { dtConnection = provider . openDataTransferConnection ( ) ; } finally { provider . dispose ( ) ; } synchronized ( abortLock ) { ongoingDataTransfer = true ; aborted = false ; consumeAborCommandReply = false ; } try { inputStream . skip ( streamOffset ) ; dataTransferOutputStream = dtConnection . getOutputStream ( ) ; if ( modezEnabled ) { dataTransferOutputStream = new DeflaterOutputStream ( dataTransferOutputStream ) ; } if ( listener != null ) { listener . started ( ) ; } if ( tp == TYPE_TEXTUAL ) { Reader reader = new InputStreamReader ( inputStream ) ; Writer writer = new OutputStreamWriter ( dataTransferOutputStream , pickCharset ( ) ) ; char [ ] buffer = new char [ SEND_AND_RECEIVE_BUFFER_SIZE ] ; int l ; while ( ( l = reader . read ( buffer ) ) != - 1 ) { writer . write ( buffer , 0 , l ) ; writer . flush ( ) ; if ( listener != null ) { listener . transferred ( l ) ; } } } else if ( tp == TYPE_BINARY ) { byte [ ] buffer = new byte [ SEND_AND_RECEIVE_BUFFER_SIZE ] ; int l ; while ( ( l = inputStream . read ( buffer ) ) != - 1 ) { dataTransferOutputStream . write ( buffer , 0 , l ) ; dataTransferOutputStream . flush ( ) ; if ( listener != null ) { listener . transferred ( l ) ; } } } } catch ( IOException e ) { synchronized ( abortLock ) { if ( aborted ) { if ( listener != null ) { listener . aborted ( ) ; } throw new FTPAbortedException ( ) ; } else { if ( listener != null ) { listener . failed ( ) ; } throw new FTPDataTransferException ( "I/O error in data transfer" , e ) ; } } } finally { if ( dataTransferOutputStream != null ) { try { dataTransferOutputStream . close ( ) ; } catch ( Throwable t ) { ; } } try { dtConnection . close ( ) ; } catch ( Throwable t ) { ; } dataTransferOutputStream = null ; synchronized ( abortLock ) { wasAborted = aborted ; ongoingDataTransfer = false ; aborted = false ; } } } finally { r = communication . readFTPReply ( ) ; touchAutoNoopTimer ( ) ; if ( r . getCode ( ) != 150 && r . getCode ( ) != 125 ) { throw new FTPException ( r ) ; } r = communication . readFTPReply ( ) ; if ( ! wasAborted && r . getCode ( ) != 226 ) { throw new FTPException ( r ) ; } if ( consumeAborCommandReply ) { communication . readFTPReply ( ) ; consumeAborCommandReply = false ; } } if ( listener != null ) { listener . completed ( ) ; } } }
target:  This method appends data to an existing file on the remote server. Calling this method blocks the current thread until the operation is completed. The operation could be interrupted by another thread calling abortCurrentDataTransfer(). The method will break with a FTPAbortedException.