使用包org.w3c.tidy.Tidy的Tidy的parse方法转化Html和Xml。
下载包并解压(下载地址https://sourceforge.net/projects/jtidy/)
把jar包引入项目:过程是这样的
右击项目名 Build Path --->Configure Build Path--->Libraries--->Add Exter JARS...(找到所需的jar就OK了)
源码示例:
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import org.w3c.tidy.Tidy;
public class HTML2XML {
private String url;
private String outFileName;
private String errOutFileName;
public HTML2XML(String url, String outFileName, String errOutFileName) {
super();
this.url = url;
this.outFileName = outFileName;
this.errOutFileName = errOutFileName;
}
public static void main(String [] args) {
String weburl = "https://www.baidu.com/";
String fileurl = "c:\\temp\\html2xml.xml";
String errurl = "c:\\temp\\error.txt";
System.out.println("the program is running");
HTML2XML t = new HTML2XML(weburl,fileurl,errurl);
t.convert();
System.out.println("running is end");
}
private void convert() {
URL u; //需要导URL包
/*需要在读取文件的同时做其他操作,使用缓冲流*/
BufferedInputStream in;//BufferedInputStream:处理流(高级流),缓冲输入流
FileOutputStream out;
Tidy tidy = new Tidy();
tidy.setXmlOut(true);
try {
//将错误文件保存到文件中
tidy.setErrout(new PrintWriter(new FileWriter(errOutFileName),true));
u = new URL(url);
//创建一个输入输出流
in = new BufferedInputStream(u.openStream());
out = new FileOutputStream(outFileName);
//转换文件
tidy.parse(in, out);
in.close();
out.close();
} catch (IOException e) {
System.out.println(this.toString()+e.toString());
}
}
}
重新复习了一下BufferedInputStream,发现一个回答很棒、很通俗易懂。链接bufferedInputStream。
问:我看到您的回答:“你也看到了,在FileInputStream里有一个说明是说此方法将阻塞,意思就是说在你读一个文件输入流的时候,当读到某个位置的时候,如果做一些其他处理(比如说接受一部分字节做一些处理等等)这个时候输入流在什么位置就是什么位置,不会继续往下读,而BufferedInputStream虽然也有一个read方法,但是从名字就可以看出,它带有一个缓冲区,它是一个非阻塞的方法,在你读到某个位置的时候,做一些处理的时候,输入流可能还会继续读入字节,这样就达到了缓冲的效果。
对于性能要求不高的时候,用哪个都无所谓,但是如果有性能要求,建议你还是用BufferedInputStream。”
能不能举个例子呢?
答:我觉得您可能是不太了解“堵塞”的意思吧!
假设一个文件的长度是100个字节,要将之读取到内存中,再假设您每次只读取10个字节,那么读完整个文件是不是读取10次的呀?
假设老板让你完成100件事情,老板说,你每天只完成10件就可以了,难道你非得等到第十天才完成第100件事情吗?有一天您在中午下班前就完成了10件事情,下午您不妨多干一点,那么也许在第9天的时候就完成了100件事情。
同理,BufferedInputStream有可能会读取比您规定的更多的东西到内存,以减少访问IO的次数,
总之您要记住一句话,访问IO的次数越少,性能就越高,原因就在于CPU和内存的速度》》》》远大于硬盘或其他外部设备的速度。
换一个不太恰当的例子来说,您和您的朋友一起去登山,你朋友太不给力了,走一会儿就要休息,而您呢,您的体力比他要好的多,根本不需要休息,所以每当他休息的时候,您得等着他,您那时候什么也干不了,这就叫堵塞,堵塞就是说您有能力干某事,但是迫于某种原因您什么也干不了,只能干等。所以您朋友休息的次数越少,你们两个到达山顶所花费的时间就越少。CPU访问硬盘的次数越少,程序就越快。BufferedInputStream在小型文件中的性能优势无法体现出来,假设您将以个2G大小的文件从D盘完全复制到E盘,性能之优势便展露无疑!
问:首先 谢谢您耐心的讲解。让我更深刻的了解了阻塞的概念。
但是我想了解的是,您说的这个BufferedInputStream在大型文件中的应用。如何应用。能不能以代码的形式 举个例子?
我想看看如何将2G大小的文件从D盘完全复制到E盘的 这种代码。
不知道能否给与帮助 谢谢
答:import java.io.*;
public class SS {
public static void main(String[] args) throws Exception {
File f = new File("d:\\大型数据库文件.mdf");
FileInputStream fis = new FileInputStream(f);
//如果下面的语句使用BufferedOutputStream来修饰则带来更好的性能现。
FileOutputStream fos = new FileOutputStream("e:\\" + f.getName());
int length = 0;
byte[] b = new byte[1024];
while((length = fis.read(b)) != -1)
{
fos.write(b, 0, length);
}
fos.close();
fis.close();
}
}