android檔案下載與儲存

來源:互聯網
上載者:User

在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。那麼現在把整個頭顯示出來看看它到底長什麼樣子:


上面這個小圖就是在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中。

效果如下:


那麼既然已經讀到了檔案的檔案的內容,那下面就把這個檔案儲存起來。 儲存檔案

那麼要把檔案儲存到哪裡呢。

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看看這個檔案內容是不是完整

至此,下載與儲存檔案就做完了,下載比上傳還要簡單一點吧。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.