摘要:用的流從網(wǎng)上下載一個(gè)視頻原理就是用對(duì)象與目標(biāo)地址建立一個(gè)鏈接,用流的方式從這個(gè)鏈接上把視頻的二進(jìn)制數(shù)據(jù)讀取下載然后再寫(xiě)入本地文件。然后循環(huán)依次寫(xiě)入緩存的大小,直至結(jié)束。
用Java的IO流從網(wǎng)上下載一個(gè)視頻
原理:就是用URL對(duì)象與目標(biāo)地址建立一個(gè)鏈接,用IO流的方式從這個(gè)鏈接上把視頻的二進(jìn)制數(shù)據(jù)讀取下載然后再寫(xiě)入本地文件。
因?yàn)樾〉鼙容^菜的緣故,不會(huì)下載那些加了密的視頻鏈接,這里我就找了一個(gè)沒(méi)有假面的url來(lái)做測(cè)試:http://aqiniu.tangdou.com/C79...
代碼思路代碼實(shí)現(xiàn)先建立一個(gè)鏈接對(duì)象,獲取到網(wǎng)頁(yè)的鏈接;
從鏈接對(duì)象獲取到輸入流,讀取數(shù)據(jù);
建立一個(gè)輸出流,向本地文件寫(xiě)入數(shù)據(jù)。
獲取鏈接對(duì)象
public class download { //定義一個(gè)HttpURLConnection在外面,因?yàn)橐趂inally中關(guān)閉 HttpURLConnection connection = null; public static void main(String[] args) { try { //獲取鏈接對(duì)象 URL url = new URL(videoUrl); HttpURLConnection connection = url.openConnection(); connection.setRequestProperty("Range","bytes=0-"); connection.connect(); if(connection.getResponseCode() / 100 != 2){ System.out.println("鏈接資源失敗..."); return; } } catch (MalformedURLException e) { e.printStackTrace(); } finally { HttpURLConnection.disconnect(); } } }
好了,現(xiàn)在來(lái)講一下上面的代碼的作用:
1.URL url = new URL(videoUrl);
就是獲取URL的資源對(duì)象,傳入的字符串就是對(duì)應(yīng)的地址;
2.HttpURLConnection connection = url.openConnection();
是獲取鏈接對(duì)象,就是靠這個(gè)對(duì)象來(lái)獲取流;
3.connection.setRequestProperty("Range","bytes=0-");
Range代表讀取的范圍,bytes=0-代表從0字節(jié)到最大字節(jié),意味著讀取所有資源
4.connection.connect();
與網(wǎng)頁(yè)建立李鏈接,鏈接成功后就可以獲得流;
5.connection.getResponseCode() / 100 != 2
這一個(gè)判斷代表的是,如果建立鏈接返回的相應(yīng)代碼是200到300間就為成功,否則鏈接失敗
獲取流實(shí)現(xiàn):
InputStream inputStream = connection.getInputStream();
獲取流只需要一行代碼,從連接對(duì)象直接get。
實(shí)現(xiàn)文件的寫(xiě)入:這里采用的是RandomAccessFile這個(gè)的對(duì)象。
String fileName = url.getFile(); fileName = fileName.substring(fileName.lastIndexOf("/")+1); RandomAccessFile randomAccessFile = new RandomAccessFile(fileName,"rw");
1.第一行代碼是獲取文件名稱,這里說(shuō)明一下,根據(jù)這個(gè)url來(lái)看,我們獲取的fileName是/C79EBFF6107CE4389C33DC5901307461-20.mp4,意思是getFile獲取的是.com后面的路徑,所以我這里用截取字符串的方式來(lái)把文件名獲取了,當(dāng)然也可以自己設(shè)置隨機(jī)的文件名
2.字符串截取
3.建立文件寫(xiě)入對(duì)象
下面貼出完整的實(shí)現(xiàn)代碼:
package download; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; public class DownloadVideo { private static String videoUrl = "http://aqiniu.tangdou.com/C79EBFF6107CE4389C33DC5901307461-20.mp4"; private static final int MAX_BUFFER_SIZE = 1000000; public static void main(String[] args) { HttpURLConnection connection = null; InputStream inputStream = null; RandomAccessFile randomAccessFile = null; try { // 1.獲取連接對(duì)象 URL url = new URL(videoUrl); connection = (HttpURLConnection) url.openConnection(); connection.setRequestProperty("Range", "bytes=0-"); connection.connect(); if(connection.getResponseCode() / 100 != 2) { System.out.println("連接失敗..."); return; } // 2.獲取連接對(duì)象的流 inputStream = connection.getInputStream(); //已下載的大小 int downloaded = 0; //總文件的大小 int fileSize = connection.getContentLength(); String fileName = url.getFile(); fileName = fileName.substring(fileName.lastIndexOf("/") + 1); // 3.把資源寫(xiě)入文件 randomAccessFile = new RandomAccessFile(fileName,"rw"); while(downloaded < fileSize) { // 3.1設(shè)置緩存流的大小 byte[] buffer = null; if(fileSize - downloaded >= MAX_BUFFER_SIZE) { buffer = new byte[MAX_BUFFER_SIZE]; }else { buffer = new byte[fileSize - downloaded]; } // 3.2把每一次緩存的數(shù)據(jù)寫(xiě)入文件 int read = -1; int currentDownload = 0; long startTime = System.currentTimeMillis(); while(currentDownload < buffer.length) { read = inputStream.read(); buffer[currentDownload ++] = (byte) read; } long endTime = System.currentTimeMillis(); double speed = 0.0; if(endTime - startTime > 0) { speed = currentDownload / 1024.0 / ((double)(endTime - startTime)/1000); } randomAccessFile.write(buffer); downloaded += currentDownload; randomAccessFile.seek(downloaded); System.out.printf("下載了進(jìn)度:%.2f%%,下載速度:%.1fkb/s(%.1fM/s)%n",downloaded * 1.0 / fileSize * 10000 / 100,speed,speed/1000); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { try { connection.disconnect(); inputStream.close(); randomAccessFile.close(); } catch (IOException e) { e.printStackTrace(); } } } public static void demo() { try { URL url = new URL(videoUrl); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
這里在補(bǔ)充說(shuō)明上面的代碼,MAX_BUFFER_SIZE是我設(shè)置的緩存大小,在注釋3.1那里判斷當(dāng)前剩余的下載大小是否大于緩存之,如果不大于就把緩存的大小設(shè)為剩余的。
while(currentDownload < buffer.length) { read = inputStream.read(); buffer[currentDownload ++] = (byte) read; }
這段代碼是按照緩存的大小,讀寫(xiě)該大小的字節(jié)。然后循環(huán)依次寫(xiě)入緩存的大小,直至結(jié)束。
這樣的優(yōu)勢(shì)在于,不用讓硬件頻繁的寫(xiě)入,可以提高效率和保護(hù)硬盤(pán)吧
控制臺(tái)輸出結(jié)果:
下載了進(jìn)度:11.59%,下載速度:388.0kb/s(0.4M/s)
下載了進(jìn)度:23.19%,下載速度:262.5kb/s(0.3M/s)
下載了進(jìn)度:34.78%,下載速度:261.0kb/s(0.3M/s)
下載了進(jìn)度:46.38%,下載速度:258.3kb/s(0.3M/s)
下載了進(jìn)度:57.97%,下載速度:260.0kb/s(0.3M/s)
下載了進(jìn)度:69.57%,下載速度:260.9kb/s(0.3M/s)
下載了進(jìn)度:81.16%,下載速度:257.4kb/s(0.3M/s)
下載了進(jìn)度:92.75%,下載速度:252.3kb/s(0.3M/s)
下載了進(jìn)度:100.00%,下載速度:286.5kb/s(0.3M/s)
好了,以上就是下載視頻的簡(jiǎn)單實(shí)現(xiàn),小弟也是剛學(xué)的,可能有許多地方不是很好,請(qǐng)不吝指教。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/77229.html
摘要:在給老師做項(xiàng)目的這個(gè)期間,我也發(fā)現(xiàn)慕課網(wǎng),然后便貪婪的在上面學(xué)習(xí),其實(shí)現(xiàn)在看看上面的教學(xué)也是一些基礎(chǔ),想要真的學(xué)到很多,必須做實(shí)際項(xiàng)目,遇到問(wèn)題,然后去百度或者谷歌這個(gè)問(wèn)題,看別人的博客中怎么教你解決。 前言:想當(dāng)初我也是個(gè)無(wú)知騷年,學(xué)完學(xué)校的C語(yǔ)言基礎(chǔ)課程之后也就再也沒(méi)有什么想法了(期間還看了看JAVA,但是發(fā)現(xiàn)并不能夠?qū)W好,索性就放棄了),由于當(dāng)時(shí)期末C語(yǔ)言程序答辯的時(shí)候,我自己仿...
摘要:在給老師做項(xiàng)目的這個(gè)期間,我也發(fā)現(xiàn)慕課網(wǎng),然后便貪婪的在上面學(xué)習(xí),其實(shí)現(xiàn)在看看上面的教學(xué)也是一些基礎(chǔ),想要真的學(xué)到很多,必須做實(shí)際項(xiàng)目,遇到問(wèn)題,然后去百度或者谷歌這個(gè)問(wèn)題,看別人的博客中怎么教你解決。 前言:想當(dāng)初我也是個(gè)無(wú)知騷年,學(xué)完學(xué)校的C語(yǔ)言基礎(chǔ)課程之后也就再也沒(méi)有什么想法了(期間還看了看JAVA,但是發(fā)現(xiàn)并不能夠?qū)W好,索性就放棄了),由于當(dāng)時(shí)期末C語(yǔ)言程序答辯的時(shí)候,我自己仿...
摘要:在給老師做項(xiàng)目的這個(gè)期間,我也發(fā)現(xiàn)慕課網(wǎng),然后便貪婪的在上面學(xué)習(xí),其實(shí)現(xiàn)在看看上面的教學(xué)也是一些基礎(chǔ),想要真的學(xué)到很多,必須做實(shí)際項(xiàng)目,遇到問(wèn)題,然后去百度或者谷歌這個(gè)問(wèn)題,看別人的博客中怎么教你解決。 前言:想當(dāng)初我也是個(gè)無(wú)知騷年,學(xué)完學(xué)校的C語(yǔ)言基礎(chǔ)課程之后也就再也沒(méi)有什么想法了(期間還看了看JAVA,但是發(fā)現(xiàn)并不能夠?qū)W好,索性就放棄了),由于當(dāng)時(shí)期末C語(yǔ)言程序答辯的時(shí)候,我自己仿...
摘要:學(xué)習(xí)完多線程之后可以通過(guò)下面這些問(wèn)題檢測(cè)自己是否掌握,下面這些問(wèn)題的答案以及常見(jiàn)多線程知識(shí)點(diǎn)的總結(jié)在這里??蛇x數(shù)據(jù)結(jié)構(gòu)與算法如果你想進(jìn)入大廠的話,我推薦你在學(xué)習(xí)完基礎(chǔ)或者多線程之后,就開(kāi)始每天抽出一點(diǎn)時(shí)間來(lái)學(xué)習(xí)算法和數(shù)據(jù)結(jié)構(gòu)。 我自己總結(jié)的Java學(xué)習(xí)的系統(tǒng)知識(shí)點(diǎn)以及面試問(wèn)題,已經(jīng)開(kāi)源,目前已經(jīng) 35k+ Star。會(huì)一直完善下去,歡迎建議和指導(dǎo),同時(shí)也歡迎Star: https://...
摘要:但發(fā)現(xiàn)導(dǎo)出來(lái)的沒(méi)有高亮語(yǔ)法沒(méi)有語(yǔ)法高亮咋看啊,所以到這里我就放棄了,將就用一下博客園生成的吧爬蟲(chóng)學(xué)習(xí)上面提供的接口是一個(gè)生成一個(gè)文件,我是不可能一個(gè)一個(gè)將鏈接和標(biāo)題放上去生成的因?yàn)椴┛蛨@上發(fā)的也將近篇了。 前言 只有光頭才能變強(qiáng) 之前有讀者問(wèn)過(guò)我:3y你的博客有沒(méi)有電子版的呀?我想要份電子版的。我說(shuō):沒(méi)有啊,我沒(méi)有弄過(guò)電子版的,我這邊有個(gè)文章導(dǎo)航頁(yè)面,你可以去文章導(dǎo)航去找來(lái)看呀..然后...
閱讀 3055·2021-11-16 11:51
閱讀 2663·2021-09-22 15:02
閱讀 3820·2021-08-04 10:21
閱讀 3706·2019-08-30 15:43
閱讀 2010·2019-08-30 11:04
閱讀 3654·2019-08-29 17:14
閱讀 553·2019-08-29 12:16
閱讀 2986·2019-08-28 18:31