Android Http實(shí)現(xiàn)文件的上傳和下載
最近做一個(gè)項(xiàng)目,其中涉及到文件的上傳和下載功能,大家都知道,這個(gè)功能實(shí)現(xiàn)其實(shí)已經(jīng)爛大街了,遂、直接從網(wǎng)上蕩了一堆代碼用,結(jié)果,發(fā)現(xiàn)網(wǎng)上的代碼真是良莠不齊,不是寫的不全面,就是有問題,于是自己重新整理了一番,把它們發(fā)出來,希望更多人能受用。
文件上傳
通過org.apache.commons.httpclient.HttpClient來實(shí)現(xiàn)文件上傳,該jar包可以直接從網(wǎng)上所搜、下載。
/** * @param mContext 上下文 * @param targetUrl 文件上傳地址 * @param filePath 文件路徑 */ public void uploadFile(final Activity mContext, String targetUrl, final String filePath) { System.out.println("targetUrl: " + targetUrl + " filePath: " + filePath); if (TextUtils.isEmpty(filePath)) { Toast.makeText(mContext, "文件不存在", Toast.LENGTH_SHORT).show(); return; } final PostMethod filePost = new PostMethod(targetUrl) {//這個(gè)用來中文亂碼 public String getRequestCharSet() { return "UTF-8"; } }; try { final HttpClient client = new HttpClient(); File file = new File(filePath); if (file.exists() && file.isFile()) { long fileSize = file.length(); if (fileSize >= 5 * 1024 * 1024) { Toast.makeText(mContext, "文件不得大于5M", Toast.LENGTH_SHORT).show(); return; } } else { Toast.makeText(mContext, "文件不存在", Toast.LENGTH_SHORT).show(); return; } // 上傳文件和參數(shù) Part[] parts = new Part[]{new CustomFilePart(file.getName(), file), new StringPart("filename", file.getName(), "UTF-8")}; filePost.setRequestEntity(new MultipartRequestEntity(parts, filePost.getParams())); new Thread(new Runnable() { @Override public void run() { int statuscode = 0; try { statuscode = client.executeMethod(filePost); } catch (IOException e) { e.printStackTrace(); } final int finalStatuscode = statuscode; mContext.runOnUiThread(new Runnable() { @Override public void run() { if (finalStatuscode == HttpStatus.SC_OK) { Toast.makeText(mContext, "上傳成功", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(mContext, "上傳失敗", Toast.LENGTH_SHORT).show(); } } }); } }).start(); } catch (Exception ex) { ex.printStackTrace(); } }
HttpClient的使用,常常會(huì)遇到亂碼問題,我們主要在兩個(gè)地方解決亂碼問題:
•復(fù)寫PostMethod 的getRequestCharSet,指定請(qǐng)求編碼
final PostMethod filePost = new PostMethod(targetUrl) {//這個(gè)用來中文亂碼 public String getRequestCharSet() { return "UTF-8"; } };
•自定義FilePart,指定請(qǐng)求參數(shù)編碼
/** * 解決中文文件名亂碼 */ public class CustomFilePart extends FilePart { public CustomFilePart(String filename, File file) throws FileNotFoundException { super(filename, file); } protected void sendDispositionHeader(OutputStream out) throws IOException { super.sendDispositionHeader(out); String filename = getSource().getFileName(); if (filename != null) { out.write(EncodingUtil.getAsciiBytes(FILE_NAME)); out.write(QUOTE_BYTES); out.write(EncodingUtil.getBytes(filename, "UTF-8")); out.write(QUOTE_BYTES); } } }
使用CustomFilePart添加參數(shù):
Part[] parts = new Part[]{new CustomFilePart(file.getName(), file), new StringPart("filename", file.getName(), "UTF-8")}; filePost.setRequestEntity(new MultipartRequestEntity(parts, filePost.getParams()));
文件下載
通過HttpURLConnection下載文件。
/** * @param urlStr 文件地址 * @param path 文件保存路徑 * @param fileName 文件名 * @return 文件的絕對(duì)路徑 */ public String downFile(String urlStr, String path, String fileName) { InputStream inputStream = null; String filePath = null; try { FileUtils fileUtils = new FileUtils(); //判斷文件是否存在 if (fileUtils.isFileExist(path + fileName)) { System.out.println("exits"); filePath = SDPATH + path + fileName; } else { //得到io流 inputStream = getInputStreamFromURL(urlStr); //從input流中將文件寫入SD卡中 File resultFile = fileUtils.write2SDFromInput(path, fileName, inputStream); if (resultFile != null) { filePath = resultFile.getPath(); } } } catch (Exception e) { e.printStackTrace(); } finally { try { if (inputStream != null) inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } return filePath; } /** * 根據(jù)URL得到輸入流 * * @param urlStr * @return */ public InputStream getInputStreamFromURL(String urlStr) { HttpURLConnection urlConn; InputStream inputStream = null; try { url = new URL(urlStr); urlConn = (HttpURLConnection) url.openConnection(); inputStream = urlConn.getInputStream(); } catch (Exception e) { e.printStackTrace(); } return inputStream; }
文件下載其實(shí)很簡單,說白了,就是通過HTTP獲取InputStream ,然后通過解析InputStream 并寫入到文件即可。
讀取Inputstream并寫入到SDCard。
/** * 將一個(gè)InputStream里面的數(shù)據(jù)寫入到SD卡中 * * @param path 文件保存路徑 * @param fileName 文件保存的名字 * @param input 文件輸入流 * @return 文件 */ public File write2SDFromInput(String path, String fileName, InputStream input) { File file = null; OutputStream output = null; try { // 創(chuàng)建文件夾 createSDDir(path); // 創(chuàng)建文件 file = createSDFile(path + fileName); // 開啟輸出流,準(zhǔn)備寫入文件 output = new FileOutputStream(file); // 緩沖區(qū) byte[] buffer = new byte[FILESIZE]; int count; while ((count = input.read(buffer)) != -1) { // 這里,請(qǐng)一定按該方式寫入文件,不然時(shí)而會(huì)出現(xiàn)文件寫入錯(cuò)誤,數(shù)據(jù)丟失問題 output.write(buffer, 0, count); } output.flush(); } catch (Exception e) { e.printStackTrace(); } finally { try { output.close(); input.close(); } catch (IOException e) { e.printStackTrace(); } } return file; }
Inputstream寫入到sdcard卡中,有個(gè)很重要的地方,先看下OutputStream 的write方法:
我推薦使用第二個(gè)方法write(byte[] b, int off, int len) ,目的是為了避免數(shù)據(jù)丟失。所以寫文件代碼如下:
while ((count = input.read(buffer)) != -1) { // 這里,請(qǐng)一定按該方式寫入文件,不然時(shí)而會(huì)出現(xiàn)文件寫入錯(cuò)誤,數(shù)據(jù)丟失問題 output.write(buffer, 0, count); }
源碼地址:https://github.com/zuiwuyuan/Http_Uploader_Downloader
以上便是我整理的Android Http實(shí)現(xiàn)文件的上傳和下載方法,希望對(duì)更多的人有所幫助。
相關(guān)文章
Android?NotificationListenerService通知監(jiān)聽服務(wù)使用
這篇文章主要為大家介紹了Android?NotificationListenerService通知監(jiān)聽服務(wù)使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11Android實(shí)現(xiàn)文字翻轉(zhuǎn)動(dòng)畫的效果
本文實(shí)現(xiàn)了Android程序文字翻轉(zhuǎn)動(dòng)畫的實(shí)現(xiàn),具有一定的參考價(jià)值,有需要的朋友可以了解一下。2016-10-10Android Support Annotations資料整理
這篇文章主要介紹了Android Support Annotations資料整理的相關(guān)資料,需要的朋友可以參考下2017-05-05Android BroadcastReceiver常見監(jiān)聽整理
這篇文章主要介紹了Android BroadcastReceiver常見監(jiān)聽整理的相關(guān)資料,需要的朋友可以參考下2016-10-10android Socket實(shí)現(xiàn)簡單聊天小程序
這篇文章主要為大家詳細(xì)介紹了android Socket實(shí)現(xiàn)簡單聊天小程序,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06android實(shí)現(xiàn)音樂播放器進(jìn)度條效果
這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)音樂播放器進(jìn)度條效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04淺析Android手機(jī)衛(wèi)士關(guān)閉自動(dòng)更新
保存數(shù)據(jù)的四種方式,網(wǎng)絡(luò),廣播提供者,SharedPreferences,數(shù)據(jù)庫。接下來通過本文給大家介紹android手機(jī)衛(wèi)士關(guān)閉自動(dòng)更新的相關(guān)知識(shí),感興趣的朋友一起學(xué)習(xí)吧2016-04-04Android獲取SDcard目錄及創(chuàng)建文件夾的方法
今天小編就為大家分享一篇Android獲取SDcard目錄及創(chuàng)建文件夾的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-08-08android 震動(dòng)和提示音的實(shí)現(xiàn)代碼
這篇文章主要介紹了android 震動(dòng)和提示音的實(shí)現(xiàn)代碼,代碼簡單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12Android使用CountDownTimer模擬短信驗(yàn)證倒計(jì)時(shí)
這篇文章主要為大家詳細(xì)介紹了Android使用CountDownTimer模擬短信驗(yàn)證倒計(jì)時(shí),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07