文件下载(java+android)

文件下载(java+android

一、普通的文件下载

a) Java实现普通文件下载

i. 指定所要下载的path(网页文件的路径)

ii. 将path转换为httpurlconnection对象

iii. 得到返回值(这一步才是真正的获取数据内容)

iv. 指定要保存的目录,在该目录下创建相应的文件

v. 获得inputstream对象,实现文件的获取

vi. 将inputstream中的内容写入到文件中即可

b) 注意

i. 通过outputstream或者bytearrayoutputstream写出数据的时候,一定要注意使用.writebyte,begin,end),这个方法,不然,如果你使用write(byte),那么它学出去的大小就是你的数组长度,也就是new byte[x]中的x的大小。

c) 代码(down_file

二、多线程断点文件下载

a) Java实现普通文件下载

i. 跟上述代码差不多

ii. 设置一个头参数conn.setrequestproperty(“Range”,”bytes=”+开始位置+”-”+结束位置),这句代码就是告诉服务器,你要下载文件的开始位置和结束位置,然后服务器就只会跟你传这段内容。这段代码的位置不能放在getresponsecode后面,因为我们知道调用getresponsecode之后,就相当于实现了联网,那时候设置头参数没有意义。而且那时候设置它会报错java.lang.IllegalStateException: Already connected,一个以链接的错误。

iii. 特别重要的是这个返回值getresponsecode不是200,而是206,很多人联网发现没有打印错误,但是又没有内容就是因为他们判断的是是否等于200,返回206是因为我们向网络请求数据时,使用了Accept-Ranges、或者Content-length(这个没尝试,可以自己去试一下),只要有这两个请求参数,那么如果成功它将返回206(注:http返回值是2xx的都表示成功返回)

iv. 在断点下载的时候我们使用到了RandomAccessFile这个类,它的构造函数中的第二个参数是设置文件的模式,r--只读,rw--可读可写(写的时候先放缓存),rwd--直接写不放入缓存,rws--当你代码的原数据(附加东西,比如开发者签名之类的东西)改变将会被直接写入。Randomaccessfile是根据一个file创建而来的,它的存在就是为了读取或者写入这个file值,所以我们可以通过randomaccessfile来操作文件。

v. Randomaccessfile写入数据,应该先调用seek(int a)的方法指明开始写入的位置,然后调用randomaccessfile.writebyte)的方法将byte值写入进去。

b) 注意

i. 使用Content_lengthranges的返回值是206,不是200,只要返回2xx都表示返回成功

三、多线程断点续传下载

a) 概述:在多线程下载的源码上,我们只要添加一个文件,记录我们我们断点下载的位置

b) 具体实现

i. 在主函数中通过一个randomaccessfile.setlength(length),来指定我们创建文件的长度,当然这个文件指定之后,无论你是否给你的文件中添加内容,那么你的文件大小就永远是这个了。

ii. 我们在一个文件中存储文件的位置的时候使用的是randomaccessfile来操作哪个file,因为randomaccessfile里面有一个readlongwritelong等写入基本数据类型的方法,每一个基本数据都有长度,如果你调用writelong写入一个数据,那么你可以在你的文件中发现,它用8为来保存,假如你存入的是23,那么它会空出6位,这样我们读取的时候可以先调用它的seek方法(因为每个占的位数固定,所以我们想获取数据只要用基本数据类型长度*我们存的第几个数)就可获取了。

iii. 当然,我们存储我们下载的长度和存储下载长度的时候一定要使用线程同步,线程同步十分的简单,synchronized(类型),将我们想同步的内容全部放到这个里面就可以了。

iv. 我们可以调用randomaccessfile.write方法来写入文件,当然你的使用seek方法指明你开始写入的位置。

c) 注意

i. 在线程同步时候,我们在保存下载长度的文件夹,读取的时候一定要注意,因为如果没有值,那么我们调用write方法的时候就会报错,所以我们的判断那个文件是否存在,而我们不可能把所有的代码都放在同步线程里,不然就逝去可断点下载的意义,个人建议使用两个同步。一个是判断存储文件长度的文件是否存在,一个是同步下载数据保存。

d) 代码down_file/down_3

四、Android实现

a) 将上面的内容作为调用函数就可以实现。

b) 注意问题

i. 权限,不仅仅要读写SDCARD、访问网络的权限,还需要mount_unmount_files,因为在上述代码中,我们使用了randomaccessfile,它的构造函数中要传入一个参数”r”,”rw”,”rwd”,”rws”,这几个是设定文件可读可写,是否经由缓存,是否经由缓存是文件系统的内容,相当于操纵了硬件,所以我们要假如mount_unmount_files这个权限

ii. 在主线程中不能实现联网,这是新版本的android的规定,所以很多培训机构的视频貌似都存在这个问题,其实你可以看下android线程就可以实现这步一部分内容了

iii. 在非主线程中不可以操作UI,但是进度条除外,进度条跟textview不一样,在android版本中可能考虑到它的运行环境,然后觉得可以在非主线程操作它,所以它是唯一可以在非主线程中操作的UI,其实根据MVC的规定,在主线程中操作UI,在非主线程做操作,这样让代码的耦合度降低。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值