question: public static int patchLessMemory ( RandomAccessFile oldFile , int oldsize , byte [ ] diffBuf , int diffSize , File newFile , int extLen ) throws IOException { if ( oldFile == null || oldsize <= 0 ) { return RETURN_OLD_FILE_ERR ; } if ( newFile == null ) { return RETURN_NEW_FILE_ERR ; } if ( diffBuf == null || diffSize <= 0 ) { return RETURN_DIFF_FILE_ERR ; } int commentLenPos = oldsize - extLen - 2 ; if ( commentLenPos <= 2 ) { return RETURN_OLD_FILE_ERR ; } DataInputStream diffIn = new DataInputStream ( new ByteArrayInputStream ( diffBuf , 0 , diffSize ) ) ; diffIn . skip ( 8 ) ; long ctrlBlockLen = diffIn . readLong ( ) ; long diffBlockLen = diffIn . readLong ( ) ; int newsize = ( int ) diffIn . readLong ( ) ; diffIn . close ( ) ; InputStream in = new ByteArrayInputStream ( diffBuf , 0 , diffSize ) ; in . skip ( BSUtil . HEADER_SIZE ) ; DataInputStream ctrlBlockIn = new DataInputStream ( new GZIPInputStream ( in ) ) ; in = new ByteArrayInputStream ( diffBuf , 0 , diffSize ) ; in . skip ( ctrlBlockLen + BSUtil . HEADER_SIZE ) ; InputStream diffBlockIn = new GZIPInputStream ( in ) ; in = new ByteArrayInputStream ( diffBuf , 0 , diffSize ) ; in . skip ( diffBlockLen + ctrlBlockLen + BSUtil . HEADER_SIZE ) ; InputStream extraBlockIn = new GZIPInputStream ( in ) ; OutputStream outStream = new FileOutputStream ( newFile ) ; try { int oldpos = 0 ; int newpos = 0 ; int [ ] ctrl = new int [ 3 ] ; while ( newpos < newsize ) { for ( int i = 0 ; i <= 2 ; i ++ ) { ctrl [ i ] = ctrlBlockIn . readInt ( ) ; } if ( newpos + ctrl [ 0 ] > newsize ) { outStream . close ( ) ; return RETURN_DIFF_FILE_ERR ; } byte [ ] buffer = new byte [ ctrl [ 0 ] ] ; if ( ! BSUtil . readFromStream ( diffBlockIn , buffer , 0 , ctrl [ 0 ] ) ) { outStream . close ( ) ; return RETURN_DIFF_FILE_ERR ; } byte [ ] oldBuffer = new byte [ ctrl [ 0 ] ] ; if ( oldFile . read ( oldBuffer , 0 , ctrl [ 0 ] ) < ctrl [ 0 ] ) { outStream . close ( ) ; return RETURN_DIFF_FILE_ERR ; } for ( int i = 0 ; i < ctrl [ 0 ] ; i ++ ) { if ( oldpos + i == commentLenPos ) { oldBuffer [ i ] = 0 ; oldBuffer [ i + 1 ] = 0 ; } if ( ( oldpos + i >= 0 ) && ( oldpos + i < oldsize ) ) { buffer [ i ] += oldBuffer [ i ] ; } } outStream . write ( buffer ) ; newpos += ctrl [ 0 ] ; oldpos += ctrl [ 0 ] ; if ( newpos + ctrl [ 1 ] > newsize ) { outStream . close ( ) ; return RETURN_DIFF_FILE_ERR ; } buffer = new byte [ ctrl [ 1 ] ] ; if ( ! BSUtil . readFromStream ( extraBlockIn , buffer , 0 , ctrl [ 1 ] ) ) { outStream . close ( ) ; return RETURN_DIFF_FILE_ERR ; } outStream . write ( buffer ) ; outStream . flush ( ) ; newpos += ctrl [ 1 ] ; oldpos += ctrl [ 2 ] ; oldFile . seek ( oldpos ) ; } ctrlBlockIn . close ( ) ; diffBlockIn . close ( ) ; extraBlockIn . close ( ) ; } finally { oldFile . close ( ) ; outStream . close ( ) ; } return RETURN_SUCCESS ; }
target:  BSPatch using less memory size. Memory size = diffFile size + max block size extLen   the length of the apk external info. set 0 if has no external info.