import Ġorg . apache . http . client . methods . Closeable HttpResponse Ċ import Ġorg . apache . http . client . methods . HttpGet Ċ import Ġorg . apache . http . impl . client . HttpClient s Ċ import Ġorg . apache . http . util . Entity Utils Ċ import Ġjava . io . File Ċ import Ġjava . io . Random Access File Ċ import Ġjava . net . Http URLConnection Ċ import Ġjava . net . URL Ċ import Ġjava . nio . charset . StandardCharsets Ċ import Ġjava . util . concurrent .* Ċ Ċ class ĠUnsupported Url Exception ( message : ĠString ?) Ġ: ĠException ( message ) Ċ Ċ data Ġclass ĠRange ( val Ġstart : ĠLong , Ġval Ġend : ĠLong ) Ċ Ċ class ĠSlice Download Ġprivate Ġconstructor ( private Ġval Ġurl : ĠString , Ġprivate Ġval Ġlocation : ĠString , Ġprivate Ġvar Ġmax Slice : ĠInt , Ġprivate Ġvar Ġheader : ĠMutable Map < String , ĠString >? Ġ= Ġnull ) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġsn iff Validator Ġ= Ġ" bytes Ġ\\ d - \\ d / (? < Total Byte Length >. (\\ d + )) ". to Regex () ĊĠĠĠ Ġprivate Ġvar Ġtotal Size : ĠLong ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġslice Size : ĠLong ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġlower Bound : ĠLong Ġ= Ġ 2 Ġshl Ġ 1 7 ĊĠĠĠ Ġprivate Ġvar Ġs liced : ĠArray < Range ?> ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( max Slice Ġ> Ġ 1 6 ) Ġthrow ĠIllegalArgumentException (" max Slice Ġcannot Ġover Ġ 1 6 ") ĊĠĠĠĠĠĠĠ Ġs liced Ġ= Ġs liced () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġs liced (): ĠArray < Range ?> Ġ{ ĊĠĠĠĠĠĠĠ Ġtotal Size Ġ= Ġvalidate Sn iffer () ĊĠĠĠĠĠĠĠ Ġslice Size Ġ= ĠMath . ceil ( total Size !! Ġ/ Ġmax Slice . toDouble ()). to Long () ĊĠĠĠĠĠĠĠ Ġif Ġ( slice Size !! Ġ< Ġlower Bound ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmax Slice Ġ= ĠMath . ceil ( total Size !! Ġ/ Ġlower Bound . toDouble ()). toInt () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġslice Size Ġ= Ġlower Bound ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġarray Ġ= ĠarrayOf Null s < Range >( max Slice Ġ- Ġ 1 ) ĊĠĠĠĠĠĠĠ Ġvar Ġallocated : ĠLong Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġallocated Ġ+= Ġslice Size !! ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 1 Ġuntil Ġmax Slice ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġslice Size !!. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġallocated Ġ+= Ġthis ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġarray [ i Ġ- Ġ 1 ] Ġ= Ġwhen ( i ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 1 Ġ-> ĠRange ( 0 , Ġallocated ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmax Slice Ġ-> ĠRange ( allocated Ġ+ Ġ 1 , ĠLong . MIN _ VALUE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠRange ( allocated Ġ- Ġthis Ġ+ Ġ 1 , Ġallocated ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġarray ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġvalidate Sn iffer (): ĠLong Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsn iff Header : ĠMutable Map < String , ĠString > Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( header Ġ== Ġnull ) Ġmap Of (" Range " Ġto Ġsn iff Range ) Ġas ĠMutable Map < String , ĠString > Ġelse ĠHashMap ( header ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis [" Range "] Ġ= Ġsn iff Range ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġresponse Ġ= Ġrequest ( url , Ġsn iff Header ). all Headers ĊĠĠĠĠĠĠĠ Ġval Ġtotal Ġ= Ġresponse . find Ġ{ Ġit . name Ġ== Ġ" Content - Range " Ġ} ?. value Ġ?: Ġthrow ĠUnsupported Url Exception (" request Ġurl Ġdoes Ġnot Ġsupport Ġget Ġpart Ġof Ġresource ") ĊĠĠĠĠĠĠĠ Ġreturn Ġsn iff Validator . match Ent ire ( total ) !!. groups [" Total Byte Length "] !!. value . apply Ġ{ Ġprintln ( this ) Ġ}. to Long () ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprivate Ġfun Ġrequest ( url : ĠString , Ġheader : ĠMap < String , ĠString >? Ġ= Ġnull ): ĠClose able HttpResponse Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġget Ġ= ĠHttp Get ( url ) ĊĠĠĠĠĠĠĠ Ġheader ?. forEach Ġ{ Ġk , Ġv Ġ-> Ġget . add Header ( k , Ġv ) Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġclient Ġ= ĠHttpClient s . create Default () ĊĠĠĠĠĠĠĠ Ġreturn Ġclient . execute ( get ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġallocate Task ( range : ĠRange , Ġlocation : ĠString , Ġon Progress Changed Callback : Ġ(( Long ) Ġ-> ĠUnit )? Ġ= Ġnull , ĠonComplete Callback : Ġ(() Ġ-> ĠUnit )? Ġ= Ġnull , Ġon Exception Callback : Ġ(( Exception ) Ġ-> ĠUnit )? Ġ= Ġnull ): Ġ() Ġ-> ĠUnit Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġheader Ġ= Ġif Ġ( header Ġ== Ġnull ) Ġmap Of (" Range " Ġto Ġ" bytes =${ range . start }-${ if ( range . end Ġ== ĠLong . MIN _ VALUE ) Ġ"" Ġelse Ġrange . end . toString () }") Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ ĠHashMap ( header ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis [" Range "] Ġ= Ġ" bytes =${ range . start }-${ range . end }" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdownload Task ( url , Ġlocation , Ġheader , Ġrange . start , Ġon Progress Changed Callback , ĠonComplete Callback , Ġon Exception Callback ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdownload Task ( url : ĠString , Ġlocation : ĠString , Ġheader : ĠMap < String , ĠString >, Ġstart Pos : ĠLong , Ġon Progress Changed Callback : Ġ(( Long ) Ġ-> ĠUnit )? Ġ= Ġnull , ĠonComplete Callback : Ġ(() Ġ-> ĠUnit )? Ġ= Ġnull , Ġon Exception Callback : Ġ(( Exception ) Ġ-> ĠUnit )? Ġ= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ ĠFile ( location . substring ( 0 , Ġlocation . lastIndexOf ('\\ ')) ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! exists ()) Ġmkdir s () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġvar Ġbyte Read : ĠInt ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhttp URLConnection Ġ= Ġ( URL ( url ). open Connection () Ġas ĠHttp URLConnection ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġheader . forEach Ġ{ Ġthis . setRequest Property ( it . key , Ġit . value ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhttp URLConnection . inputStream . use Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( File ( location ). length () Ġ== Ġhttp URLConnection . content Length Long ) Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRandom Access File ( File ( location ), Ġ" r wd "). use Ġ{ Ġrandom Access Stream Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrandom Access Stream . seek ( start Pos ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbuffer Ġ= ĠByteArray ( 1 0 2 4 ); Ġvar Ġk : ĠLong Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( it . read ( buffer ). apply Ġ{ Ġbyte Read Ġ= Ġthis Ġ} Ġ!= Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Progress Changed Callback ?. invoke (( k ++ Ġ/ Ġhttp URLConnection . content Length Long . toDouble () Ġ* Ġ 1 0 0 0 0 0 . toDouble ()). to Long ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrandom Access Stream . write ( buffer , Ġ 0 , Ġbyte Read ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Exception Callback ?. invoke ( e ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠonComplete Callback ?. invoke () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġexecute ( on Progress Changed Callback : Ġ(( Long ) Ġ-> ĠUnit )? Ġ= Ġnull , ĠonComplete Callback : Ġ(() Ġ-> ĠUnit )? Ġ= Ġnull , Ġon Exception Callback : Ġ(( Exception ) Ġ-> ĠUnit )? Ġ= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtask Process Pool Ġ= ĠExec utors . new Fixed ThreadPool ( max Slice ) ĊĠĠĠĠĠĠĠ Ġval Ġstop Watch Ġ= ĠCount DownLatch ( max Slice ) ĊĠĠĠĠĠĠĠ Ġfor Ġ( task Ġin Ġs liced ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtask Process Pool . execute Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġallocate Task ( task !! , Ġlocation , Ġon Progress Changed Callback , ĠonComplete Callback , Ġon Exception Callback ). invoke () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstop Watch . count Down () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstop Watch . await () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ignored : ĠInterruptedException ) Ġ{} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġrun ( url : ĠString , Ġlocation : ĠString , Ġheader : ĠMutable Map < String , ĠString >? Ġ= Ġnull , Ġmax Slice : ĠInt ? Ġ= Ġnull , Ġon Progress Changed Callback : Ġ(( Long ) Ġ-> ĠUnit )? , ĠonComplete Callback : Ġ(() Ġ-> ĠUnit )? , Ġon Exception Callback : Ġ(( Exception ) Ġ-> ĠUnit )? ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinstance Ġ= ĠSlice Download ( url , Ġlocation , Ġmax Slice Ġ?: Ġ 2 Ġshl Ġ 3 , Ġheader ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinstance . execute ( on Progress Changed Callback , ĠonComplete Callback , Ġon Exception Callback ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval Ġsn iff Range Ġ= Ġ" bytes = 0 - 0 " ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun Ġmain () Ġ{ ĊĠĠĠ ĠSlice Download . run ( ĊĠĠĠĠĠĠĠ Ġ" http :// cn - hb xy - cm cc - v - 0 9 . ac g video . com / up gc xcode / 5 0 / 8 9 / 7 8 7 8 8 9 5 0 / 7 8 7 8 8 9 5 0 - 1 - 8 0 . fl v ? expires = 1 5 5 1 7 2 2 1 0 0 & platform = pc & ss ig = v 1 on h 2 Mu 6 nn lo D _ E 0 H - PN w & oi = 6 6 4 1 1 3 9 0 0 & tr id = 7 d 9 8 edb 6 4 e 7 d 4 5 b 8 8 1 b 5 6 7 3 f 7 3 0 0 5 6 a 8 & n fb = ma PY q po el 5 MI 3 q O UX 6 Y p RA == & n fc = 1 ", ĊĠĠĠĠĠĠĠ Ġ" D :\\ Multi Thread Download Test \\ video . fl v ", ĊĠĠĠĠĠĠĠ Ġmutable Map Of ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Accept " Ġto Ġ"* /* ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Accept - Encoding " Ġto Ġ" gzip , Ġdef late , Ġbr ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Accept - Language " Ġto Ġ" en - US , en ; q = 0 . 9 , zh - CN ; q = 0 . 8 , zh ; q = 0 . 7 ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" User - Agent " Ġto Ġ" Mozilla / 5 . 0 Ġ( Windows ĠNT Ġ 1 0 . 0 ; ĠWin 6 4 ; Ġx 6 4 ) ĠAppleWebKit / 5 3 7 . 3 6 Ġ( KHTML , Ġlike ĠGecko ) ĠChrome / 7 2 . 0 . 3 6 2 6 . 1 1 9 ĠSafari / 5 3 7 . 3 6 ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Refer er " Ġto Ġ" https :// www . b ilib ili . com / video / av 4 4 9 8 6 9 4 9 ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Origin " Ġto Ġ" https :// www . b ilib ili . com ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Connection " Ġto Ġ" keep - alive ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Host " Ġto Ġ" cn - hb xy - cm cc - v - 0 9 . ac g video . com " ĊĠĠĠĠĠĠĠ Ġ), ĊĠĠĠĠĠĠĠĠ 1 0 , ĊĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprintln ("${ Thread . currentThread (). name }: Ġ$ it % ") ĊĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" complete ") ĊĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . printStackTrace () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ) Ċ } Ċ