小白一个,有很多不懂的地方。
先上一个界面Activity代码
/**声明控件*/
private Button downloadTxt;
private Button downloadFile;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/**找到控件*/
downloadTxt = findViewById(R.id.downloadTxt);
downloadFile = findViewById(R.id.downloadFile);
/**绑定监听器*/
downloadTxt.setOnClickListener(new downloadTxtListener());
downloadFile.setOnClickListener(new downloadFileListener());
}
class downloadTxtListener implements View.OnClickListener{
@Override
public void onClick(View v) {
HttpDownloader httpDownloader = new HttpDownloader();
String string =httpDownloader.download("http://www.9ku.com/downlrc.php?id=668803");
System.out.println(string);
}
}
class downloadFileListener implements View.OnClickListener{
@Override
public void onClick(View v) {
HttpDownloader httpDownloader = new HttpDownloader();
int result = httpDownloader.downloadFile(
"http://61.136.107.33/file3.data.weipan.cn/68505953/85f20f855a5d5707abf0ce587c6c58e6feed6b75?ip=1530198740,123.13.202.228&ssig=QnYrXxebAC&Expires=1530199340&KID=sae,l30zoo1wmz&fn=R.City%26Adam+Levine-Locked+Away.mp3&se_ip_debug=123.13.202.228&from=1221134&wsrid_tag=5b34f625_xiangwangtong30_32119-44031&wsiphost=local","111","111");
System.out.println(result);
}
}
上图功能简单,一个按钮用来从网络上下载文本文件;一个按钮用来从网络上下载任何形式的文件;
再上SD卡部分的代码:
package com.example.urien.httpdownload;
import android.os.Environment;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class FileUtils {
private String SDPATH;
public String getSDPATH() {
return SDPATH;
}
public FileUtils() {
/**得到当前外部存储设备的根目录*/
SDPATH = Environment.getExternalStorageDirectory() + "/";
}
/**
* 在SD卡上创建文件
*/
public File creadSDFile(String fileName) throws IOException {
File file = new File(SDPATH + fileName);
file.createNewFile();
return file;
}
/**
* 在SD卡上创建目录
*/
public File creadSDDir(String dirName) {
File dir = new File(SDPATH + dirName);
dir.mkdir();
return dir;
}
/**
* 判断SD卡上的文件是否存在
*/
public boolean isFileExist(String fileName) {
File file = new File(SDPATH + fileName);
return file.exists();
}
/**
* 讲一个InputStream里面的数据写到SD卡中
* path :写入的路径(目录)
* fileName :文件名
* inputStream :携带数据的输入流
*
* 返回值 File:写入后的文件所对应的对象
*/
public File writeInputStream2SD(String path, String fileName, InputStream inputStream) {
File file = null;
OutputStream outputStream = null;
try {
/**
* 要讲一个文件写到SD卡里面
* 1.先创建一个目录
* 2.在这个目录里面创建一个文件
* 3.把要写入的文件数据写到创建好的文件里面
* */
//创建一个目录
creadSDDir(path);
//创建一个文件
file = creadSDFile(path + fileName);
//根据这个文件对象创建一个输出流,这个输出流将会对这个文件写入数据
outputStream = new FileOutputStream(file);
//创建一个4K的字节缓存
byte buffer[] = new byte[1024 * 4];
/**
* 先从输入流里面读取4K字节数据到buffer里面
* 再把这个数据通过输出流写入到文件中
* 每次读写4K直到全部读取并写入完毕
* */
while ((inputStream.read(buffer) != -1)) {
outputStream.write(buffer);
}
//操作完毕后晴空下输出流
outputStream.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
//关闭输出流
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return file;
}
}
这里面包含了有很多封装好的功能方法:比如取得SDCARD路径、判断SDCARD路径文件是否存在、向SD卡创建文件、创建目录、向指定路径写入文件等等,中文注释也很详细。
注意SD卡操作需要加入操作手机外部存储的权限:
android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
最后上Http部分代码:
package com.example.urien.httpdownload;
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 HttpDownloader {
/**
* 声明一个URL对象
*/
private URL url = null;
/**
* 根据URL下载文件,下载的文件需要是文本文件
* urlStr :网络链接地址
* 返回值是一个String对象,这个对象包含了文本里面的内容
*
*
* 从网络上下载一个文本文件的步骤:
*
* 1.创建一个URL对象
* 2.通过URL对象,创建一个HttpURLConnection对象
* 3.得到InputSteam
* 4.从InputStream当中读取数据
*/
public String download(String urlStr) {
/**声明一个字符串数组对象*/
StringBuffer stringBuffer = new StringBuffer();
String line = null;
/**生成一个BufferedReader对象,
* 这个类里面有一个readLine方法很好用
* 可以每次读取一行数据
* */
BufferedReader bufferedReader = null;
try {
/**创建一个URL对象,传入参数为网络下载地址
* 这样可以生成一个代表这个网络地址的URL对象
* */
url = new URL(urlStr);
/**创建一个Http连接
* 这个对象就代表了这个网络地址的一个http链接
* */
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
/**
* httpURLConnection.getInputStream() 以字节的方式读取需要下载文件
* InputStreamReader 把一个字节流转换成字符流
* BufferedReader 把字符流套上一个BufferedReader装饰方便一行一行的读取
*/
bufferedReader = new BufferedReader(
new InputStreamReader(
httpURLConnection.getInputStream()
)
);
/**
* 以行为单位读取数据,每次读取一行,并把这一行字符返回到line中
* 当line不为null指针,说明line里面有数据
* 这时候变把读取的的这行字符line对象添加到将要返回的stringBuffer中
* 当字符读取完毕,readLine方法没有读取到数据便返回一个null,此时跳出while
* */
while ((line = bufferedReader.readLine()) != null) {
stringBuffer.append(line);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
bufferedReader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return stringBuffer.toString();
}
/**
* 下载任意形式的文件
*
* urlStr :需要下载文件的文件网络下载链接
* path :下载完文件后所存放的SD卡里面的目录
* FileName :下载好后文件的命名
* 整形返回值
* -1 下载文件出错
* 0 下载文件成功
* 1 代表文件已经存在
*/
public int downloadFile(String urlStr, String path, String fileName) {
/**声明一个输入流*/
InputStream inputStream = null;
try {
//生成一个FileUtils对象
FileUtils fileUtils = new FileUtils();
if (fileUtils.isFileExist(path + fileName)) {
return 1;//文件已经存在了
} else {
//得到网络下载地址多对应的下载链接
inputStream = getInputStreamFromUrl(urlStr);
//向SD卡写入得到输入流
File file = fileUtils.writeInputStream2SD(path,fileName,inputStream);
if(file == null)
return -1;
}
} catch (Exception e) {
e.printStackTrace();
return -1;
} finally {
try{
inputStream.close();
}catch (Exception e){
e.printStackTrace();
}
}
return 0;
}
/**
* 根据url得到输入流
*
* urlStr :网络链接地址
*
* 返回参数:网络连接多对应的数据流
*/
public InputStream getInputStreamFromUrl(String urlStr)
throws MalformedURLException, IOException {
//通过下载链接作为参数得到一个URL的对象
url = new URL(urlStr);
//调用url的openConnection方法得到一个代表这个下载链接的http链接对象
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
//通过这个http链接得到这个链接所对应的输入流
InputStream inputStream = httpURLConnection.getInputStream();
return inputStream;
}
}
这里面包含有通过url连接下载文本类型的文件;通过url链接下载任意形式的文件、通过url连接得到文件的输入流三个功能。
注意这里要添加手机的访问网络权限:
android:name="android.permission.INTERNET"/>
因为知识有限,测试的app并没有成功从网络上下载文件。更不会搭建服务器,所以一切都是迷茫。点击按钮LogCat打印出的信息如下:
06-28 23:00:56.586 15138-15138/com.example.urien.httpdownload D/libc-netbsd: [getaddrinfo]: hostname=www.9ku.com; servname=(null); cache_mode=(null), netid=0; mark=0
[getaddrinfo]: ai_addrlen=0; ai_canonname=(null); ai_flags=4; ai_family=0
06-28 23:13:21.401 15138-15138/com.example.urien.httpdownload D/libc-netbsd: [getaddrinfo]: hostname=61.136.107.33; servname=(null); cache_mode=(null), netid=0; mark=0
[getaddrinfo]: ai_addrlen=0; ai_canonname=(null); ai_flags=4; ai_family=0
06-28 23:13:21.402 15138-15138/com.example.urien.httpdownload D/libc-netbsd: [getaddrinfo]: hostname=61.136.107.33; servname=(null); cache_mode=(null), netid=0; mark=0
[getaddrinfo]: ai_addrlen=0; ai_canonname=(null); ai_flags=4; ai_family=0
如果有知道的大神,还请指教,十分感谢。
By Urien 2018年6月28日 23:14:09