在android网络编程学习与实战之旅一中,实现了把一个或者多个文件上传的自己搭建的服务器中,那么这一节,显而易见的内容当然是怎么把文件下载下来。这里依旧使用java.net包中的HttpUrlConnection来实现。关于下载后的文件,可以有两种处理方式,一种是把它保存下来,另一种是把它显示出来,比如图片文字等可以下载后直接显示出来。

为了更具直观性的学习Android文件下载,这里首先尝试把一个txt格式的文件下载下来显示在TextView中。

那么,我想到的第一个问题是:我怎么获得下载文件的文件名?因为我要保存它,我得知道它的名字。

响应头里面有有文件名的信息吗?

获取响应头

首先声明一下,这里要下载的文件在自己搭建的apache更目录下的pic目录下,是一个hello.txt文件,它的URL是这样的:

http://192.168.0.103:8088/pic/hello.txt

为了解决这两个问题,这里首先读出响应头,也就是使用:

Map<String, List<String>> map = httpURLConnection.getHeaderFields();
这个函数就是用来获取响应头的,它返回一个Map,key是一个字符串,values是一个List。那么现在把整个头显示出来看看它到底长什么样子:

android文件下载与保存_第1张图片

上面这个小图就是在TextView中显示出来的响应头的信息,只要获得了它的响应头的这个Map,显示应该就没什么问题了吧,所以这里就不贴代码了,最后这个方法我会一并贴出来。

仔细找来找去,也没有找到任何关于filaname的信息,那怎么办呢?因为设置请求url的时候,里面已经包含了filename,所以暂时从它里面提取出来吧,大家谁有好办法欢迎留言。提取的代码很简单:

            int location =requesl.lastIndexOf('/');            String filename = requesl.substring(location+1);
这里的requesl就是url的字符串。

获取文件内容

获取文件的内容就是读HttpUrlConnection下getInputStream这个流了,具体怎么读代码中有注释,现在把这个方法完整的贴出来:

   public static void doDownLoadFile(Handler handler){        final String requesl = "http://192.168.0.103:8088/pic/hello.txt";        URL url = null;        HttpURLConnection httpURLConnection = null;        try {            url = new URL(requesl);            //1 提取url中的文件名            int location =requesl.lastIndexOf('/');            String filename = requesl.substring(location+1);            //2.打开连接            httpURLConnection = (HttpURLConnection) url.openConnection();            //3 获得相应头            Map<String, List<String>> map = httpURLConnection.getHeaderFields();            Set<String> keySet = map.keySet();            StringBuilder builder = new StringBuilder();            builder.append("filename : "+filename+"\n");            List<String> values ;            if (keySet != null){                for (String s:keySet                     ) {                    builder.append(s+":");                    values = map.get(s);                    for (String ss:values                         ) {                        builder.append(ss);                    }                    builder.append("\n");                }            }            //4. 获得读入流            InputStream in = httpURLConnection.getInputStream();            //4.1获得文件长度            int length = Integer.valueOf(map.get("Content-Length").get(0));            byte []bbb = new byte[length];            //读出文件            in.read(bbb);            String ssss = new String(bbb);            builder.append(ssss);            //通知UI更新            Message message = new Message();            Bundle bundle= new Bundle();            bundle.putString("name",builder.toString());            message.setData(bundle);            handler.sendMessage(message);            //关闭流            in.close();            httpURLConnection.disconnect();        } catch (MalformedURLException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }

通过这个代码,我们就把响应头和文件内容全部显示到TextView中了。这个函数的handler使用来通知UI更新的,在MainActivity中有一个Hanler处理消息:

        handler = new Handler(new Handler.Callback() {            @Override            public boolean handleMessage(Message msg) {                Log.d("hello",msg.getData().getString("name"));                textView.setText(msg.getData().getString("name"));                return true;            }        });
在消息处理函数中获取Message中的数据,把它显示在TextView中。

效果如下:

android文件下载与保存_第2张图片

那么既然已经读到了文件的文件的内容,那下面就把这个文件保存起来。

保存文件

那么要把文件保存到哪里呢?

assets目录下肯定是不行的,因为它是只读的,SD卡貌似是个不错的选择,但是不是所有的手机都有SD卡。那这里就简单的保存在应用程序默认的文件目录下面吧。

   public static void doSaveFileInDefaultFileDir(Context context,String filename,byte[] bb){        //1.首先判断文件是否存在,存在就什么都不做,不存在就保存它        File file = new File(context.getFilesDir(),filename);        if(!file.exists()){            try {                file.createNewFile();                FileOutputStream fout = new FileOutputStream(file);                fout.write(bb);                fout.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }

这就是我们的保存文件的函数,它非常简单,首先判断文件是否存在,不存在就创建一个。注意,创建的时候使用的是
context.getFilesDir(),它会获得/data/data/包名/files路劲,这个目录是应用程序私有的目录,应用程序又读写权限。
然后我们获取到这个文件的输出流,把我们从网络上读到的数据写入流中,最后关闭流就可以了。
注意:为了使用context.getFilesDir()函数,这里给这个函数加了一个Context的参数,那么在前面doDownLoadFile方法中也需要
加入这个参数声明。在调用doDownLoadFile方法的地方也不要忘了添加这个参数。
最后,使用adb shell命令进入手机看看文件是不是保存成功了。我这里使用的是android模拟器,它可以获得root权限:
1.adb shell
2.su
3.cd /data/data/com.konka.networktest/files

4.ls 就会发现这个文件已经存在了。

5.cat hello.txt看看这个文件内容是不是完整

至此,下载与保存文件就做完了,下载比上传还要简单一点吧。

更多相关文章

  1. android 扫描文件(sdcard添加新的音乐文件时候后,可扫描到)
  2. Android NDK开发——操作JNI函数以及复杂对象的传递
  3. Android stutio 中怎么将XML中文件快速findById——Android Layo
  4. init进程 && 解析Android启动脚本init.rc && 修改它使不启动andr
  5. Android Developers:保存文件
  6. Android中读取assets目录下的文件详细介绍
  7. android studio导入gbk编码的工程文件导致的乱码问题
  8. gen文件无法生成
  9. Android 数据缓存-文件存储

随机推荐

  1. Android 短信链接打开APP
  2. Android:实现隐藏应用功能
  3. 赵雅智:android使用adb命令详解附图
  4. Intent组件构成,解析机制
  5. Android(安卓)enum(枚举类型)使用详解
  6. java.io.IOException:Can't read [F:\..
  7. Android开发全程记录(十五)——android调用
  8. [置顶] Android省电开发 浅析
  9. Android管理篇
  10. Android属性动画—实现第三方登录的上拉