一、乱码产生的原因:
public static void main(String[] args) throws IOException {
try {
//生成写文件对象 (写文件者需要某个文件对象)
File file = new File(Text_File_Path);
if(!file.exists()) {
File fileDir = file.getParentFile();
if(!fileDir.isDirectory()) {
fileDir.mkdirs();
}
file.createNewFile();
}
// 生成下载对象
Socket webclient = new Socket("www.bnu.edu.cn", 80);
//生成写对象 写到台主机的某个端口
PrintWriter result = new PrintWriter(webclient.getOutputStream(), true);
//生成bufferredreader对象 需要inputstreamreader,需要inputstream
BufferedReader receiver = new BufferedReader(new InputStreamReader(webclient.getInputStream()));
InputStream webInput = webclient.getInputStream();
//发送HTTP request请求
result.println("GET / HTTP/1.1");
result.println("Host: bnu.edu.cn");
result.println("Connection: Close");
result.println();
//接收HTTP Response 返回的结果信息
boolean bRet = true;
StringBuilder sBuilder = new StringBuilder();
while (bRet) {
if (receiver.ready()) {
byte[] bytes = new byte[1024];
int count = 0;
while (count != -1) {
count = webInput.read(bytes);
String tempStr = new String(bytes,"utf-8");
System.out.println(tempStr);
sBuilder.append(tempStr);
}
bRet = false;
}
}
// 显示获得的网页正文,打印到控制台
//System.out.println(new String(sBuffer.toString().getBytes("gbk"),"utf-8"));
//System.out.println(sBuilder.toString());
fpWriter.write(sBuilder.toString());
webclient.close();
fpWriter.close();
} catch (UnknownHostException e) {
System.err.println("无法访问指定主机.");
System.exit(1);
} catch (IOException e) {
System.err.println("下载失败,请检查输入地址是否正确。");
System.exit(1);
}
}
由于在网络上传输的数据是基于字节流,在 java 中对应的就是byte。然而不同的编码对同样的字节会进行不同的组织,形成不同的形式展现在我们眼前。就比如:拿记事本记录“我爱你”这三个中文字符,在计算机中是不认识这种东西的,它只认识0和1,然而你用记事本编辑的时候,当你输入这三个字的时候,其实记事本
已经按照默认的编码帮你转化成了0和1。当你写网页的时候,网页编辑器就会去读取你设置的网页编码,否则就按照默认编码把你写好的网页转化成0和1的组合。
这个时候,如果你用 java 代码去获取这个页面,对方的计算机就会把这些0和1的组合发到网络上传输,传输过来之后,如果你不按照它原来的编码格式进行转化过来给人看,人就会看到乱码,除非运气好,刚好你用的编码与他原来的编码兼容。
在java中如果需要将字节0和1的组合给人看,就要把字节转化成字符串,这个时候你如果没有指定编码格式,java就自作主张,按照他的默认格式unicode编码,把字节组织成字符串,然后unicode编码你也懂啦,基本上和中文字符等编码是不兼容的,于是就会乱码的离谱,如果你决定在转化成字符串之前,显示的指定编码,那么恭喜你,你已经要疯了。原因是什么,是因为你在网上拿到的网页你怎么知道是什么编码呢?幸运的是,英文字符大部分编码都是兼容的。所以你可以按照任意编码先将读到的东西转化成字符串,然后判断它的字符编码,然后再按照它正确的编码重新全部转化。但是你发现没有,这样是不是很麻烦啊!有没有简单的办法呢?
呵呵,恭喜你,有的!方法就是,不进行字符转码,我直接把字节流往文本里面写,你想想会发生什么呢?
注意:
在实际开发中出现的
乱码
问题实际上都是在字符流和字节流之间转化不统一而造成的
。
package chapter2;
import java.io.*;
import java.net.*;
import java.nio.CharBuffer;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
public class WebCrawler {
private static String Text_File_Path = "E:\\workshop\\ch2\\htmlsrc.html";
FileWriter fpWriter = new FileWriter(file);//需要最后关闭
//连接某台主机的某个端口
}