android文件下载与保存

在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看看这个文件内容是不是完整

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

你可能感兴趣的:(android,文件下载,网络,NetWork)