十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
InputStreamReader in = new InputStreamReader(new FileInputStream(“demo.txt”),”UTF-8”);
目前成都创新互联已为上千多家的企业提供了网站建设、域名、网页空间、网站托管维护、企业网站设计、河东网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。
给InputStreamReader指定解码编码,这样二者统一就不会出现乱码了。
下面说说字符输出流。
字符输出流的原理和字符输入流的原理一样,也可以看做是包装流,其底层还是采用字节输出流来写文件。只是字符输出流根据指定的编码将字符转换为字节的。字符输出流的主要类是:OutputStreamWriter。Java api解释如下:OutputStreamWriter 是字符流通向字节流的桥梁:使用指定的 charset 将要向其写入的字符编码为字节。它使用的字符集可以由名称指定或显式给定,否则可能接受平台默认的字符集。说的很明白了,它需要一个编码将写入的字符转换为字节,如果没有指定则采用GBK编码,那么输出的字节都将是GBK编码,生成的文件也是GBK编码的。如果采用以下方式构造OutputStreamWriter:
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(“dd.txt”),”UTF-8”);
那么写入的字符将被编码为UTF-8的字节,生成的文件也将是UTF-8格式的。
问题二: 既然读文件要使用和文件编码一致的编码,那么javac编译文件也需要读取文件,它使用什么编码呢?
这个问题从来就没想过,也从没当做是什么问题。正是因为问题一而引发的思考,其实这里还是有东西可以挖掘的。下面分三种情况来探讨,这三种情况也是我们常用的编译java源文件的方法。
1.javac在控制台编译java类文件。
通常我们手动建立一个java文件Demo.java,并保存。此时Demo.java文件的编码为ANSI,中文操作系统下就是GBK.然后使用javac命令来编译该源文件。”javac Demo.java”。Javac也需要读取java文件,那么javac是使用什么编码来解码我们读取的字节呢?其实javac采用了操作系统默认的GBK编码解码我们读取的字节,这个编码正好也是Demo.java文件的编码,二者一致,所以不会出现乱码情况。让我们来做点手脚,在保存Demo.java文件时,我们选择UTF-8保存。此时Demo.java文件编码就是UTF-8了。我们再使用”javac Demo.java”来编译,如果Demo.java里含有中文字符,此时控制台会出现警告信息,也出现了乱码。究其原因,就是因为javac采用了GBK编码解码我们读取的字节。因为我们的字节是UTF-8编码的,所以会出现乱码。如果不信的话你可以自己试试。那么解决办法呢?解决办法就是使用javac的encoding参数来制定我们的解码编码。如下:javac -encoding UTF-8 Demo.java。这里我们指定了使用UTF-8来解码读取的字节,由于这个编码和Demo.java文件编码一致,所以不会出现乱码情况了。
2.Eclipse中编译java文件。
我习惯把Eclipse的编码设置成UTF-8。那么每个项目中的java源文件的编码就是UTF-8。这样编译也从没有问题,也没有出现过乱码。正是因为这样才掩盖了使用javac可能出现的乱码。那么Eclipse是如何正确编译文件编码为UTF-8的java源文件的呢?唯一的解释就是Eclipse自动识别了我们java源文件的文件编码,然后采取了正确的encoding参数来编译我们的java源文件。功劳都归功于IDE的强大了。
3.使用Ant来编译java文件。
Ant也是我常用的编译java文件的工具。首先,必须知道Ant在后台其实也是采用javac来编译java源文件的,那么可想而知,1会出现的问题在Ant中也会存在。如果我们使用Ant来编译UTF-8编码的java源文件,并且不指定如何编码,那么也会出现乱码的情况。所以Ant的编译命令有一个属性” encoding”允许我们指定编码,如果我们要编译源文件编码为UTF-8的java文件,那么我们的命令应该如下:
指定了编码也就相当于”javac –encoding”了,所以不会出现乱码了。
你是想通过java代码获取还是常规仅仅想知道一个java源文件的编码格式?
如果只是想知道java源文件的编码格式的话用记事本打开源文件,然后 文件-另存为 里面有个编码格式,默认就是当前文件的编码格式。
如下:
//我写了一个程序,你把文字复制到文本框中点转码按钮,就可以了
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
public class Class1 extends JFrame {
private final class AT implements ActionListener {
public void actionPerformed(ActionEvent e) {
jta.setText(fixString(jta.getText()));
}
}
public static void main(String[] args) {
JFrame jf = new Class1();
}
JTextArea jta = new JTextArea();
public Class1() {
setSize(400, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
JButton jb = new JButton("转码");
jb.addActionListener(new AT());
add(jta);
add("North", jb);
setVisible(true);
}
String fixString(String s) {
while (true) {
int index = s.indexOf("\\u");
if (index != -1) {
String s1 = s.substring(index, index + 6);
if (s1.matches("\\\\u[0-9A-F]{4}")) {
char c = (char) Integer.parseInt(s1.replace("\\u", ""), 16);
s = s.substring(0, index) + c + s.substring(index + 6);
}
} else {
break;
}
}
return s;
}
}
java中编码:URLEncoder.encode(strUri,"utf-8");
java中解码码:URLDecoder.decode(strUri,"utf-8");
java编码和解码
流读取文件,具有转换编码功能的有:OutputStreamWriter和InputStreamReader,
构造器有如:
InputStreamReader(InputStream in, String charsetName)
创建使用指定字符集的 InputStreamReader。
OutputStreamWriter(OutputStream out, String charsetName)
创建使用指定字符集的 OutputStreamWriter。
处理字符串编码问题:
重新对获取的字符串进行编码:Byte[] bytes = str.getBytes(String encodeCharsetNam);
重新对bytes进行解码,创建新的字符串对象:str = new String(Byte[] bytes,String decodeCharsetName);
一般结合使用:str = new String(str.getBytes(String encodeCharsetName),String decodeCharsetName);
例如:resultName=new String(username.getBytes("ISO-8859-1"),"UTF-8");
还可以加入判断:
if(!Charset.forName("gbk").newEncoder().canEncode(str)){str = new Strin(str.getBytes("ISO-8859-1"),"UTF-8");}else{str = new String(str.getBytes("ISO-8859-1"),"gbk");}
处理请求参数传递编码问题:
java中编码:URLEncoder.encode(strUri,"utf-8");
java中解码码:URLDecoder.decode(strUri,"utf-8");
js中编码:encodeURIComponent(strUri);encodeURI(strUri);escape(str);
js中解码:decodeURIComponent(strUri);decodeURI(strUri);unescape(str);
补充概念:
URI组件:主机、端口、路径、查询参数、片段等。
URI组件分隔符::/?#[]@,冒号用于分隔协议和主机,/用于分隔主机和 路径,?用于分隔路径和查询参数,用于分隔多个查询参数等。
URI中的不安全字符或保留字符: ! * ‘ ( ) ; : @ = + $ , / ? # [ ] 他们具有特殊作用,例如上面的分隔作用。
URI允许出现的字符:只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符,其他字符均需要经过编码之后才能出现在Url中,比如使用保留字符的原意,而不是特殊作用。
js向java/jsp的编码与解码:
js中编码:encodeURI(encodeURI(strUri));decodeURIComponent(decodeURIComponent(strUri));
java/jsp中解码: java.net.URLDecoder.decode(strUri,"UTF-8");
js中编码两次的问题:如果使用一次编码,在浏览器地址栏里,浏览器认为%是个转义字符,浏览器会把%与%之间的编码值,两位两位取出后进行解码。
然后再传递给处理页面,然后由处理页面进行再次解码,这样前面就缺少了一次编码过程,所以前面需要连续两次编码。