本例用到了多线程、时间函数、网络流、文件读写、正则表达式(在读取html内容response时,最好不要用正则表达式来抓捕html文本内容里的特征,因为服务器返回的多个页面的文本内容不一定使用相同的模式),是一个综合性的实例。

package javatest;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern; class urlTest
{
public static void main(String[] args) throws IOException
{
//String url = "http://www.ik6.com/meinv/10000/index.html";
String dir = "d:\\result\\201601282"; int base = 40624;
// 多线程方法,从网上下载多个图片并保存
ArrayList<Thread> threads = new ArrayList<Thread>();
urlTest test=new urlTest(); int threadCount=1;//开5个线程,用于下载
int themePerThread=1;
Date start=new Date();
System.out.println("threads start..");
for (int i = 0; i < threadCount; i++)
{
Thread t = new Thread(test.new workerThread(dir, base, themePerThread));
threads.add(t);
t.start();
base+=themePerThread;
}
for (Thread t : threads)
{
try
{
t.join();//让主线程等待此子线程执行完毕
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
System.out.println("threads complete..");
Date end=new Date();
//计算总耗时
long diff = end.getTime() - start.getTime();
String info=String.format("it takes %f seconds to run.", diff / 1000.00);
System.out.println(info); //单线程方法
// for (int themeCount = 0; themeCount < 200; themeCount++)
// {
// for (int pageIndex = 1; pageIndex <= 20; pageIndex++)
// {
// if (pageIndex==1)
// {url = String.format(
// "http://www.ik6.com/meinv/%d/index.html", base
// + themeCount);
// }
// else
// {
// url = String.format(
// "http://www.ik6.com/meinv/%d/index_%d.html", base
// + themeCount, pageIndex);
// }
//
// String data = GetResponseText(url);
// if (!IsContentPage(data))
// break;
// System.out.println(url);
// ArrayList<String> imgUrls = GetImgUrls(data);
// for (String imgUrl : imgUrls)
// {
// String imageSavedPath = String.format("%s\\%d_%d.jpg", dir,base+
// themeCount,pageIndex);
// RetrieveImg2(imgUrl, imageSavedPath);
// }
//
// }
// }
} public class workerThread implements Runnable
{ String dir = null;
int base = 0;
int themeCount = 0;
int totalPage=0;
int totalImg=0; public workerThread(String dir, int base, int themeCount)
{
this.dir = dir;
this.base = base;
this.themeCount = themeCount;
} public void run()
{
String url=null;
int pageNo=0;
for (int themeIndex = 0; themeIndex < themeCount; themeIndex++)
{
for (int pageIndex = 1; pageIndex <= 50; pageIndex++)
{
pageNo=base+ themeIndex;
if (pageIndex == 1)
{
url = String.format("http://www.ik6.com/meinv/%d/index.html", pageNo);
}
else
{
url = String.format(
"http://www.ik6.com/meinv/%d/index_%d.html",
pageNo, pageIndex);
} String data = GetResponseText(url);
if (!IsContentPage(data))
break; ArrayList<String> imgUrls = GetImgUrls(data);
for (String imgUrl : imgUrls)
{
String imageSavedPath = String.format("%s\\%d_%d.jpg",
dir, pageNo, pageIndex);
RetrieveImg2(imgUrl, imageSavedPath);
} }
} } } //日期格式化
public static String GetTimeString()
{
Date dt = new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
String s = df.format(dt);
return s;
}
//通过特征判断
public static boolean IsContentPage(String pageContent)
{
return pageContent.indexOf("<center>") != -1;
} public static ArrayList<String> GetImgUrls(String srcStr)
{
// 利用正则表达式,读取页面中所有图片的url
// Pattern p1 = Pattern.compile("<center.+\n?.+\n?</center>");
// Pattern p2 = Pattern.compile("lazysrc=\"http\\:.+\\.jpg\"");
// Matcher m = p2.matcher(srcStr);
// ArrayList<String> imgUrls = new ArrayList<String>();
// while (m.find())
// {
// String match = m.group();
// imgUrls.add(match.substring(match.indexOf("\"")+1,match.lastIndexOf("\"")));
// }
// return imgUrls; // 仅读取主题图片的url,为何不能匹配center?
// Pattern p1 = Pattern.compile("<center.+\n*.+\n*</center>");
// Pattern p2 = Pattern.compile("lazysrc=\"http\\:.+\\.jpg\"");
// Matcher m = p1.matcher(srcStr);
// ArrayList<String> imgUrls = new ArrayList<String>();
// if (m.find())
// {
// String matchCenter = m.group();
// Matcher m2 = p2.matcher(matchCenter);
// while (m2.find())
// {
// String matchImage = m2.group();
// imgUrls.add(matchImage.substring(matchImage.indexOf("\"") + 1,
// matchImage.lastIndexOf("\"")));
// }
// }
// return imgUrls; // 用字符串的indexOf方法找出所有图片的url
srcStr = srcStr.substring(srcStr.indexOf("<center"),
srcStr.indexOf("</center>"));
// Pattern p2 = Pattern.compile("lazysrc=http\\:.+\\.jpg");
srcStr = srcStr.substring(srcStr.indexOf("src="));
srcStr = srcStr.substring(srcStr.indexOf("http"),
srcStr.indexOf(".jpg") + 4);
ArrayList<String> imgUrls = new ArrayList<String>();
imgUrls.add(srcStr);
return imgUrls; } //通过url获取html页面
public static String GetResponseText(String url)
{
String response = null;
try
{
URL _url = new URL(url);
HttpURLConnection urlcon = (HttpURLConnection) _url
.openConnection();
// 获取连接
InputStream is = urlcon.getInputStream();
BufferedReader buffer = new BufferedReader(new InputStreamReader(
is, "utf-8"));
StringBuffer sb = new StringBuffer();
String line = null;
while ((line = buffer.readLine()) != null)
{
sb.append(line).append('\n');
// System.out.println(l);
}
response = sb.toString();
}
catch (Exception e)
{
e.printStackTrace();
} return response;
} //通过图片的url,获取图片并保存在本地.注意:此法有缺点
public static void RetrieveImg(String imgURL, String savepath)
{
try
{
File file = new File(savepath);
if (file.exists())
{
return;
}
else
{
file.createNewFile();
URL _url = new URL(imgURL);
HttpURLConnection urlcon = (HttpURLConnection) _url
.openConnection();
// urlcon.setRequestMethod("GET");
// 超时响应时间为5秒
// urlcon.setConnectTimeout(3 * 1000);
// 获取连接
InputStream is = urlcon.getInputStream();
byte[] buffer = new byte[1024];
FileOutputStream out = new FileOutputStream(file);
while (is.read(buffer) != -1)
;
out.write(buffer);// 为何不行
is.close();
out.close();
}
}
catch (Exception e)
{
e.printStackTrace();
}
} //通过图片的url,获取图片并保存在本地
public static void RetrieveImg2(String imgURL, String savepath)
{
try
{
File file = new File(savepath);
if (file.exists())
{
return;
}
else
{
file.createNewFile();
URL _url = new URL(imgURL);
HttpURLConnection conn = (HttpURLConnection) _url
.openConnection();
conn.setRequestMethod("GET");
// 超时响应时间为5秒
conn.setConnectTimeout(5 * 1000);
// 通过输入流获取图片数据
InputStream inStream = conn.getInputStream();
byte[] data = readInputStream(inStream);
// 写入到新文件当中
FileOutputStream out = new FileOutputStream(file);
out.write(data);
out.close();
}
}
catch (Exception e)
{
e.printStackTrace();
}
} //将输入流的内容写入内存保存起来,以便稍后写入到文件当中
public static byte[] readInputStream(InputStream inStream) throws Exception
{
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;// 关键,否则图片不完整,因为不知道写入多少
while ((len = inStream.read(buffer)) != -1)
{
outStream.write(buffer, 0, len);
}
inStream.close();
// 把outStream里的数据写入内存
return outStream.toByteArray();
}
}

Java--多线程读取网络图片并保存在本地的更多相关文章

  1. Python配合BeautifulSoup读取网络图片并保存在本地

    本例为Python配合BeautifulSoup读取网络图片,并保存在本地. BeautifulSoup可代替正则表达式,更好地解析Html文本,获取其中的指定内容,如Tag.Property等 # ...

  2. JAVA 通过url下载图片保存到本地

    //java 通过url下载图片保存到本地 public static void download(String urlString, int i) throws Exception { // 构造U ...

  3. PHP获取网络图片并保存在本地目录

    PHP获取网络图片并保存在本地目录思路: 代码如下: function file_exists_S3($url) { $state = @file_get_contents($url,0,null,0 ...

  4. Python3 获取网络图片并且保存到本地

    Python3 获取网络图片并且保存到本地 import requests from bs4 import BeautifulSoup from urllib import request impor ...

  5. Java多线程读取大文件

    前言 今天是五一假期第一天,按理应该是快乐玩耍的日子,但是作为一个北漂到京师的开发人员,实在难想出去那玩耍.好玩的地方比较远,近处又感觉没意思.于是乎,闲着写篇文章,总结下昨天写的程序吧. 昨天下午朋 ...

  6. java将base64解析图片保存到本地。

    将base64解析图片保存到本地的两个方法 /** * base64转图片 * @param base64str base64码 * @param savePath 图片路径 * @return */ ...

  7. Java从网络读取图片并保存至本地

    package cn.test.net; import java.io.File; import java.io.FileOutputStream; import java.io.InputStrea ...

  8. JAVA获取网络图片并保存到本地(随机图片接口)

    import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import j ...

  9. Java 多线程读取文件并统计词频 实例 出神入化的《ThreadPoolExecutor》

    重在展示多线程ThreadPoolExecutor的使用,和线程同步器CountDownLatch,以及相关CAS的原子操作和线程安全的Map/队列. ThreadPool主线程 1 import j ...

随机推荐

  1. HTML5——播放器

    有了H5的Video,妈妈再也不用担心我没安Flash插件了 根据Video提供的方法和属性,简单练习了一下,不说废话,直接上图片和代码 <html><head><tit ...

  2. Go语言_时间篇

    Go的time包是标准库中的包之一 不用说,几乎是开发必须用到的包之一.time包的说明文档在: http://golang.org/pkg/time/ 先注意下Overview中的一句话: The ...

  3. z-index详解

    来源于:http://www.cnblogs.com/ForEvErNoME/p/3373641.html 概念 z-index 属性设置元素的堆叠顺序.拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的 ...

  4. Git 常用命令详解(二)

    Git 是一个很强大的分布式版本管理工具,它不但适用于管理大型开源软件的源代码(如:linux kernel),管理私人的文档和源代码也有很多优势(如:wsi-lgame-pro) Git 的更多介绍 ...

  5. [转]DBA,SYSDBA,SYSOPER三者的区别

    原文地址:http://www.oracleonlinux.cn/2010/02/dba_sysdba_sysoper/ 什么是DBA?什么是SYSDBA,什么又是SYSOPER?三者究竟有何联系呢? ...

  6. 创建Car类,实例化并调用Car类计算运输的原料量是否足够

    package dx; public class Car { //构造类 public Car() { System.out.println("Car的构造类"); } //构造类 ...

  7. MVC升级以后出现"当前上下文中不存在ViewBag"的问题解决

    把自己的项目从MVC4升级到了MVC5,结果问题一大堆,View的设计环境出现了"当前上下文中不存在ViewBag"的问题: 虽然不影响编译,但是看了总是不爽,而且语法提示也没有了 ...

  8. 利用Spring中的HtmlUtils.htmlEscape(input)过滤html

    fatherModule.setModuelName(HtmlUtils.htmlEscape(fatherModule.getModuelName())); log.info(HtmlUtils.h ...

  9. c++中string类型用下标初始化后str.size()为0 输出string值为空

    你的string list是个默认构造函数,这样就没有为list分配空间,自然list[i]就会报出超出string范围的错误,可以简单更改为string list(6, '\0'),事先为list指 ...

  10. Linux强制访问控制机制模块分析之mls_type.h

    2.4.2 mls_type.h 2.4.2.1文件描述 对于mls_type.h文件,其完整文件名为security/selinux/ss/mls_types.h,该文件定义了MLS策略使用的类型. ...