用http协议下载文件,主要用到的是httpURLConnection对象,主要的步骤如下:
1. 创建HttpURLConnection对象
2.获得一个InputStream对象
3.修改权限:访问网络和写SDK卡,在Manifest.xml声明:
<uses-permission android:name="android.permission.INTERNET"/> //允许网络访问 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> //允许写入SDK卡
String urlDownload = ""; urlDownload = "http://www.baidu.com/img/baidu_sylogo1.gif"; URL url = new URL(urlDownload ); // 打开连接 URLConnection con = url.openConnection(); // 输入流 InputStream is = con.getInputStream();
如上面的代码所示,指定一个下载的目标链接,我们上面指定了一个图片地址。然后构建一个URL对象,调用该 对象的openConnection方法来建立一个数据通路(连接)。代码的最后一行使用 con.getInputStream,拿到一个输入流对象,通过这个流对象我们就可以读取到这个文件的内容了。下面要做的,就是读取这个流,将流写入我 们的本地文件。不过在这之前,我们还要说下这个方法:
//获得文件的长度 int contentLength = con.getContentLength(); System.out.println("长度 :"+contentLength);
获得文件长度的方法。ContentLength是不很熟啊。它是http协议里描述头(head)部分的描述属性之一。实际这里是发送了一个http请求,分析了返回(response)里数据内容。
我们常常会把文件下载到手机的存储卡里,所以还会用到获得存储卡路径的方法:
// 获得存储卡路径,构成 保存文件的目标路径 String dirName = ""; dirName = Environment.getExternalStorageDirectory()+"/MyDownload/"; File f = new File(dirName); if(!f.exists()) { f.mkdir(); }
Environment.getExternalStorageDirectory() 方法会返回一个字符串,指示了存储卡的路径。我们拼接字符串出一个准备存放下载文件的文件夹。并先判断文件夹是是否存在,如果不存在,则新建一个文件夹。
做完了上面的准备后,基本就能实现下载了。我们看看主要的完整代码。
下载前的准备工作:
//要下载的文件路径 String urlDownload = ""; //urlDownload = "http://192.168.3.39/text.txt"; urlDownload = "http://www.baidu.com/img/baidu_sylogo1.gif"; // 获得存储卡路径,构成 保存文件的目标路径 String dirName = ""; dirName = Environment.getExternalStorageDirectory()+"/MyDownload/"; File f = new File(dirName); if(!f.exists()) { f.mkdir(); }
下载的操作:
//准备拼接新的文件名(保存在存储卡后的文件名) String newFilename = _urlStr.substring(_urlStr.lastIndexOf("/")+1); newFilename = _dirName + newFilename; File file = new File(newFilename); //如果目标文件已经存在,则删除。产生覆盖旧文件的效果 if(file.exists()) { file.delete(); } try { // 构造URL URL url = new URL(_urlStr); // 打开连接 URLConnection con = url.openConnection(); //获得文件的长度 int contentLength = con.getContentLength(); System.out.println("长度 :"+contentLength); // 输入流 InputStream is = con.getInputStream(); // 1K的数据缓冲 byte[] bs = new byte[1024]; // 读取到的数据长度 int len; // 输出的文件流 OutputStream os = new FileOutputStream(newFilename); // 开始读取 while ((len = is.read(bs)) != -1) { os.write(bs, 0, len); } // 完毕,关闭所有链接 os.close(); is.close(); } catch (Exception e) { e.printStackTrace(); }
下面是封装的一些方法我的部分代码如下:
//从服务器下载图片到本地 private void getPhotoFromServer(List<Advert> adverts){ //读取服务器ip地址 String serverip = NetworkUtil.getDns(); //直接读取服务器的ip地址 //String serverURL = serverURLAll.substring(serverURLAll.indexOf(":")+3, serverURLAll.lastIndexOf(":")); //最好还是直接从数据库或者其他地方读取ip地址 Log.d(TAG, "server ip is " + serverip); //整合成完整的广告图片存放地址目录 String urlDownload = "http://" + serverip +":8080/proPicRecord/"; //广告图片本地sd卡存放目录 String dirName = "/sdcard/advert/"; //判断本地存放广告图片的目录是否存,不存在则新建文件夹 File f = new File(dirName); if(!f.exists()) { f.mkdir(); } //服务器上广告图片完整路径名,供下载用 String urlDownloadAll = ""; //准备拼接新的文件名(保存在存储卡后的文件名) for(int i=0; adverts!=null && i<adverts.size(); i++){ Advert advert = adverts.get(i); //下载路径添加上广告图片名字 urlDownloadAll = urlDownload + advert.getUrl(); Log.d(TAG, "The whole server download url is " + urlDownloadAll); //获取广告图片的名字,其实使用advert.getUrl()也可 String newFilename = urlDownloadAll.substring(urlDownloadAll.lastIndexOf("/")+1); //本地播放广告图片的完整路径 newFilename = dirName + newFilename; Log.d(TAG, "The local url is" + newFilename); File file = new File(newFilename); //如果目标文件已经存在,则删除,产生覆盖旧文件的效果(此处以后可以扩展为已经存在图片不再重新下载功能) if(file.exists()) { file.delete(); } try{ //构造URL URL url = new URL(urlDownloadAll); //打开连接 URLConnection con = url.openConnection(); //获得文件的长度 //int contentLength = con.getContentLength(); //System.out.println("长度 :"+contentLength); //输入流 InputStream is = con.getInputStream(); //1K的数据缓冲 byte[] bs = new byte[1024]; //读取到的数据长度 int len; //输出的文件流 OutputStream os = new FileOutputStream(newFilename); //开始读取 while ((len = is.read(bs)) != -1) { os.write(bs, 0, len); } //完毕,关闭所有链接 os.close(); is.close(); }catch(Exception e){ e.printStackTrace(); } } }
单个文件下载:
package page.util; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; public class HttpDownloaderUtil{ private URL url=null; /** * 根据URL下载文本文件,以行读取文件 */ public String download(String urlStr){ StringBuffer sb = new StringBuffer(); String line = null; BufferedReader buffer = null; try{ url = new URL(urlStr); HttpURLConnection urlConn = (HttpURLConnection)url.openConnection(); buffer = new BufferedReader(new InputStreamReader(urlConn.getInputStream())); while((line = buffer.readLine())!=null) { sb.append(line); } }catch(Exception e) { e.printStackTrace(); }finally{ try{ buffer.close(); }catch(Exception e){ e.printStackTrace(); } } return sb.toString(); } /** * 下载文件并写SD卡 * @param urlStr * @param path * @param fileName * @return 0-success,-1-fail,1-existed */ public int downFile(String urlStr,String path,String fileName){ InputStream inputStream= null; try{ FileUtil fileUtil = new FileUtil(); if(fileUtil.isFileExist(path+fileName)) return 1; else{ inputStream = getInputStreamFromUrl(urlStr); File resultFile = fileUtil.write2SDFromInput(path, fileName, inputStream); if(resultFile == null) return -1; } }catch(Exception e){ e.printStackTrace(); }finally{ try{ inputStream.close(); }catch(Exception e){ e.printStackTrace(); } } return 0; } public InputStream getInputStreamFromUrl(String urlStr) throws MalformedURLException,IOException{ url = new URL(urlStr); HttpURLConnection urlCon =(HttpURLConnection)url.openConnection(); InputStream inputStream = urlCon.getInputStream(); return inputStream; } }
文件处理的工具类:
package page.util; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import android.os.Environment; public class FileUtil{ private String SDPATH; public String getSDPATH(){ return SDPATH; } public FileUtil(){ SDPATH= Environment.getExternalStorageDirectory()+"/"; } public File createSDFile(String fileName) throws IOException{ File file = new File(SDPATH+fileName); file.createNewFile(); return file; } public File createSDDir(String dirName) { File dir = new File(SDPATH+dirName); dir.mkdir(); return dir; } public boolean isFileExist(String fileName){ File file = new File(SDPATH+fileName); return file.exists(); } public File write2SDFromInput(String path,String fileName,InputStream input){ File file = null; OutputStream output = null; try{ createSDDir(path); file = createSDFile(path+fileName); output = new FileOutputStream(file); byte buffer[] = new byte[4*1024]; while((input.read(buffer))!=-1){ output.write(buffer); } output.flush(); }catch(Exception e){ e.printStackTrace(); }finally{ try{ output.close(); } catch(Exception e){ e.printStackTrace(); } } return file; } }