做了一个很简单的音乐下载项目,从网络上相关网页抓取歌曲和歌词的
超链接地址,然后通过这个超链接将歌曲和歌词下载到本地。这样一来就
可以进行批量下载了。批量下载还会遇到一个问题,抓取的网站可能会将
你的IP地址封掉,这就需要动态切换IP,动态切换IP,可以使用拨号上网
的机器,没隔一段时间重新拨号,通常情况下就会换一个IP进行下载了。
很简单的实现,主要包括两个关键的地方,一是获取歌曲和歌词的超
链接。这个代码其实比较简单的:
URL url = new URL(urlAddr); // 转化成URL格式
URLConnection URLconnection = url.openConnection(); // 创建一个连接
HttpURLConnection httpConnection = (HttpURLConnection) URLconnection;
int responseCode = httpConnection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {// 连接正常
System.out.println("Connection ok.");
InputStream urlStream = httpConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlStream));
String sCurrentLine = ""; // 按行读取网页
String sTotalString = ""; // 存储整个网页
while ((sCurrentLine = bufferedReader.readLine()) != null)
sTotalString = sTotalString + sCurrentLine + "\r\n";
}
}
从获取到的字符流中提取歌曲和歌词的超链接,将这些超链接信息通过一个链表
或者其它什么数据结构保存起来,做为参数传递给下载相关的代码:
public void saveToFile(String destUrl,String filename) throws Exception{
File file = new File(filename);
if(file.exists()){
logger.info(file.getName()+"文件已经存在,无需下载!");
return;
}
int slashPos = filename.lastIndexOf("/");
String dir = null;
if(slashPos >= 0){
dir = filename.substring(0,slashPos);
File f = new File(dir);
if(f.isDirectory()){
;
}else{
if(!f.mkdirs()){
throw new IOException("Make Dir Fail:" + dir);
}
}
}
FileOutputStream fos = null;
BufferedInputStream bis = null;
HttpURLConnection httpUrl = null;
URL url = null;
byte[] buf = new byte[BUFFER_SIZE];
int size = 0;
boolean isNeedRetry = true;
while(isNeedRetry){
try{
isNeedRetry = false;
url = new URL(destUrl);
httpUrl = (HttpURLConnection)url.openConnection();
httpUrl.connect();
bis = new BufferedInputStream(httpUrl.getInputStream());
fos = new FileOutputStream(filename);
while((size = bis.read(buf)) != -1)
fos.write(buf,0,size);
logger.info(file.getName()+"下载完成!");
}catch(Exception e){
if(destUrl.contains(".lrc")){
}else{
if(!isNeedRetry)
logger.info("Current ip is:"+IPUtils.getInstance().getIPInfo());
isNeedRetry = true;
Thread.sleep(30000);
}
}finally{
fos.close();
bis.close();
httpUrl.disconnect();
}
}
此实现只是简单的判断一下文件是否已经下载过了,并没有添加断点续传的功能。
如果以前的文件没有下载完整,下次重新下载依旧不是完整的,这也是没有提供断
点续传会导致的问题,但是由于使用的是单线程下载,所以每次会影响的文件只有
一个,如果使用了多线程的话,那么就必须考虑增加断点续传的功能了。