摘要:用的流从网上下载一个视频原理就是用对象与目标地址建立一个链接,用流的方式从这个链接上把视频的二进制数据读取下载然后再写入本地文件。然后循环依次写入缓存的大小,直至结束。
用Java的IO流从网上下载一个视频
原理:就是用URL对象与目标地址建立一个链接,用IO流的方式从这个链接上把视频的二进制数据读取下载然后再写入本地文件。
因为小弟比较菜的缘故,不会下载那些加了密的视频链接,这里我就找了一个没有假面的url来做测试:http://aqiniu.tangdou.com/C79...
代码思路代码实现先建立一个链接对象,获取到网页的链接;
从链接对象获取到输入流,读取数据;
建立一个输出流,向本地文件写入数据。
获取链接对象
public class download { //定义一个HttpURLConnection在外面,因为要在finally中关闭 HttpURLConnection connection = null; public static void main(String[] args) { try { //获取链接对象 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(); } } }
好了,现在来讲一下上面的代码的作用:
1.URL url = new URL(videoUrl);
就是获取URL的资源对象,传入的字符串就是对应的地址;
2.HttpURLConnection connection = url.openConnection();
是获取链接对象,就是靠这个对象来获取流;
3.connection.setRequestProperty("Range","bytes=0-");
Range代表读取的范围,bytes=0-代表从0字节到最大字节,意味着读取所有资源
4.connection.connect();
与网页建立李链接,链接成功后就可以获得流;
5.connection.getResponseCode() / 100 != 2
这一个判断代表的是,如果建立链接返回的相应代码是200到300间就为成功,否则链接失败
获取流实现:
InputStream inputStream = connection.getInputStream();
获取流只需要一行代码,从连接对象直接get。
实现文件的写入:这里采用的是RandomAccessFile这个的对象。
String fileName = url.getFile(); fileName = fileName.substring(fileName.lastIndexOf("/")+1); RandomAccessFile randomAccessFile = new RandomAccessFile(fileName,"rw");
1.第一行代码是获取文件名称,这里说明一下,根据这个url来看,我们获取的fileName是/C79EBFF6107CE4389C33DC5901307461-20.mp4,意思是getFile获取的是.com后面的路径,所以我这里用截取字符串的方式来把文件名获取了,当然也可以自己设置随机的文件名
2.字符串截取
3.建立文件写入对象
下面贴出完整的实现代码:
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.获取连接对象 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.获取连接对象的流 inputStream = connection.getInputStream(); //已下载的大小 int downloaded = 0; //总文件的大小 int fileSize = connection.getContentLength(); String fileName = url.getFile(); fileName = fileName.substring(fileName.lastIndexOf("/") + 1); // 3.把资源写入文件 randomAccessFile = new RandomAccessFile(fileName,"rw"); while(downloaded < fileSize) { // 3.1设置缓存流的大小 byte[] buffer = null; if(fileSize - downloaded >= MAX_BUFFER_SIZE) { buffer = new byte[MAX_BUFFER_SIZE]; }else { buffer = new byte[fileSize - downloaded]; } // 3.2把每一次缓存的数据写入文件 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("下载了进度:%.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(); } } }
这里在补充说明上面的代码,MAX_BUFFER_SIZE是我设置的缓存大小,在注释3.1那里判断当前剩余的下载大小是否大于缓存之,如果不大于就把缓存的大小设为剩余的。
while(currentDownload < buffer.length) { read = inputStream.read(); buffer[currentDownload ++] = (byte) read; }
这段代码是按照缓存的大小,读写该大小的字节。然后循环依次写入缓存的大小,直至结束。
这样的优势在于,不用让硬件频繁的写入,可以提高效率和保护硬盘吧
控制台输出结果:
下载了进度:11.59%,下载速度:388.0kb/s(0.4M/s)
下载了进度:23.19%,下载速度:262.5kb/s(0.3M/s)
下载了进度:34.78%,下载速度:261.0kb/s(0.3M/s)
下载了进度:46.38%,下载速度:258.3kb/s(0.3M/s)
下载了进度:57.97%,下载速度:260.0kb/s(0.3M/s)
下载了进度:69.57%,下载速度:260.9kb/s(0.3M/s)
下载了进度:81.16%,下载速度:257.4kb/s(0.3M/s)
下载了进度:92.75%,下载速度:252.3kb/s(0.3M/s)
下载了进度:100.00%,下载速度:286.5kb/s(0.3M/s)
好了,以上就是下载视频的简单实现,小弟也是刚学的,可能有许多地方不是很好,请不吝指教。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/77229.html
摘要:在给老师做项目的这个期间,我也发现慕课网,然后便贪婪的在上面学习,其实现在看看上面的教学也是一些基础,想要真的学到很多,必须做实际项目,遇到问题,然后去百度或者谷歌这个问题,看别人的博客中怎么教你解决。 前言:想当初我也是个无知骚年,学完学校的C语言基础课程之后也就再也没有什么想法了(期间还看了看JAVA,但是发现并不能够学好,索性就放弃了),由于当时期末C语言程序答辩的时候,我自己仿...
摘要:在给老师做项目的这个期间,我也发现慕课网,然后便贪婪的在上面学习,其实现在看看上面的教学也是一些基础,想要真的学到很多,必须做实际项目,遇到问题,然后去百度或者谷歌这个问题,看别人的博客中怎么教你解决。 前言:想当初我也是个无知骚年,学完学校的C语言基础课程之后也就再也没有什么想法了(期间还看了看JAVA,但是发现并不能够学好,索性就放弃了),由于当时期末C语言程序答辩的时候,我自己仿...
摘要:在给老师做项目的这个期间,我也发现慕课网,然后便贪婪的在上面学习,其实现在看看上面的教学也是一些基础,想要真的学到很多,必须做实际项目,遇到问题,然后去百度或者谷歌这个问题,看别人的博客中怎么教你解决。 前言:想当初我也是个无知骚年,学完学校的C语言基础课程之后也就再也没有什么想法了(期间还看了看JAVA,但是发现并不能够学好,索性就放弃了),由于当时期末C语言程序答辩的时候,我自己仿...
摘要:学习完多线程之后可以通过下面这些问题检测自己是否掌握,下面这些问题的答案以及常见多线程知识点的总结在这里。可选数据结构与算法如果你想进入大厂的话,我推荐你在学习完基础或者多线程之后,就开始每天抽出一点时间来学习算法和数据结构。 我自己总结的Java学习的系统知识点以及面试问题,已经开源,目前已经 35k+ Star。会一直完善下去,欢迎建议和指导,同时也欢迎Star: https://...
摘要:但发现导出来的没有高亮语法没有语法高亮咋看啊,所以到这里我就放弃了,将就用一下博客园生成的吧爬虫学习上面提供的接口是一个生成一个文件,我是不可能一个一个将链接和标题放上去生成的因为博客园上发的也将近篇了。 前言 只有光头才能变强 之前有读者问过我:3y你的博客有没有电子版的呀?我想要份电子版的。我说:没有啊,我没有弄过电子版的,我这边有个文章导航页面,你可以去文章导航去找来看呀..然后...
阅读 2955·2021-11-16 11:51
阅读 2585·2021-09-22 15:02
阅读 3701·2021-08-04 10:21
阅读 3552·2019-08-30 15:43
阅读 1922·2019-08-30 11:04
阅读 3583·2019-08-29 17:14
阅读 467·2019-08-29 12:16
阅读 2917·2019-08-28 18:31