- java编码转换过程
我们总是用一个java类文件和用户进行最直接的交互(输入、输出),这些交互内容包含的文字可能会包含中文。无论这些java类是与数据库交互,
还是与前端页面交互,他们的生命周期总是这样的:
1、程序员在操作系统上通过编辑器编写程序代码并且以.java的格式保存操作系统中,这些文件我们称之为源文件。
2、通过JDK中的javac.exe编译这些源文件形成.class类。
3、直接运行这些类或者部署在WEB容器中运行,得到输出结果。
这些过程是从宏观上面来观察的,了解这个肯定是不行的,我们需要真正来了解java是如何来编码和被解码的:
第一步:当我们用编辑器编写java源文件,程序文件在保存时会采用操作系统默认的编码格式(一般我们中文的操作系统采用的是GBK编码格式)形成一个.java文件。java源文件是采用操作系统默认支持的file.encoding编码格式保存的。下面代码可以查看系统的file.encoding参数值。
System.out.println(System.getProperty("file.encoding"));
第二步:当我们使用javac.exe编译我们的java文件时,JDK首先会确认它的编译参数encoding来确定源代码字符集,如果我们不指定该编译参数,JDK首先会获取操作系统默认的file.encoding参数,然后JDK就会把我们编写的java源程序从file.encoding编码格式转化为JAVA内部默认的UNICODE格式放入内存中。
第三步:JDK将上面编译好的且保存在内存中信息写入class文件中,形成.class文件。此时.class文件是Unicode编码的,也就是说我们常见的.class文件中的内容无论是中文字符还是英文字符,他们都已经转换为Unicode编码格式了。
在这一步中对对JSP源文件的处理方式有点儿不同:WEB容器调用JSP编译器,JSP编译器首先会查看JSP文件是否设置了文件编码格式,如果没有设置则JSP编译器会调用调用JDK采用默认的编码方式将JSP文件转化为临时的servlet类,然后再编译为.class文件并保持到临时文件夹中。
第四步:运行编译的类:在这里会存在一下几种情况
1、直接在console上运行。
2、JSP/Servlet类。
3、java类与数据库之间。
- java如何编码解码
在java中主要有四个场景需要进行编码解码操作:
1:I/O操作
2:内存
3:数据库
4:javaWeb
InputStream为字节输入流的所有类的超类,Reader为读取字符流的抽象类。java读取文件的方式分为按字节流读取和按字符流读取,其中InputStream、Reader是这两种读取方式的超类。
按字节
我们一般都是使用InputStream.read()方法在数据流中读取字节(read()每次都只读取一个字节,效率非常慢,我们一般都是使用read(byte[
])),
然后保存在一个byte[]数组中,最后转换为String。在我们读取文件时,读取字节的编码取决于文件所使用的编码格式,而在转换为String过程中
也会涉及到编码的问题,如果两者之间的编码格式不同可能会出现问题。例如存在一个问题test.txt编码格式为UTF-8,那么通过字节流读取文件时所
获得的数据流编码格式就是UTF-8,而我们在转化成String过程中如果不指定编码格式,则默认使用系统编码格式(GBK)来解码操作,由于两者编
码格式不一致,那么在构造String过程肯定会产生乱码,如下:
File file = new File("C:\\test.txt");
InputStream input = new FileInputStream(file);
StringBuffer buffer = new StringBuffer();
byte[] bytes = new byte[1024];
for(int n ; (n = input.read(bytes))!=-1 ; ){
buffer.append(new String(bytes,0,n));
}
System.out.println(buffer);
输出结果:锘挎垜鏄?cm
test.txt中的内容为:我是 cm。
要想不出现乱码,在构造String过程中指定编码格式,使得编码解码时两者编码格式保持一致即可:
buffer.append(new String(bytes,0,n,"UTF-8"));
字节&字符转换
字节转换为字符一定少不了InputStreamReader。API解释如下:InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset
读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。 每次调用 InputStreamReader 中
的一个 read() 方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足
当前读取操作所需的字节。API解释非常清楚,InputStreamReader在底层读取文件时仍然采用字节读取,读取字节后它需要根据一个指定的编码
格式来解析为字符,如果没有指定编码格式则采用系统默认编码格式。
String file = "C:\\test.txt";
String charset = "UTF-8";
// 写字符换转成字节流
FileOutputStream outputStream = new FileOutputStream(file);
OutputStreamWriter writer = new OutputStreamWriter(outputStream, charset);
try {
writer.write("我是 cm");
} finally {
writer.close();
}
// 读取字节转换成字符
FileInputStream inputStream = new FileInputStream(file);
InputStreamReader reader = new InputStreamReader(
inputStream, charset);
StringBuffer buffer = new StringBuffer();
char[] buf = new char[64];
int count = 0;
try {
while ((count = reader.read(buf)) != -1) {
buffer.append(buf, 0, count);
}
} finally {
reader.close();
}
System.out.println(buffer);
- javaWeb中的编码解码
请求
客户端想服务器发送请求无非就通过四中情况:
1、URL方式直接访问。
2、页面链接。
3、表单get提交
4、表单post提交
- 解决URL中文乱码问题
encodeURI
对整个URL进行编码,它采用的是UTF-8格式输出编码后的字符串。不过encodeURI除了ASCII编码外对于一些特殊的字符也不会进行编码如:! @ # $& * ( ) = : / ; ? + ‘。
encodeURIComponent()
把URI字符串采用UTF-8编码格式转化成escape格式的字符串。相对于encodeURI,encodeURIComponent会更加强大,它会对那些在encodeURI()中不被编码的符号(; / ? : @ & = + $ , #)统统会被编码。但是encodeURIComponent只会对URL的组成部分进行个别编码,而不用于对整个URL进行编码。对应解码函数方法decodeURIComponent。
我们总是用一个java类文件和用户进行最直接的交互(输入、输出),这些交互内容包含的文字可能会包含中文。无论这些java类是与数据库交互,
还是与前端页面交互,他们的生命周期总是这样的:
1、程序员在操作系统上通过编辑器编写程序代码并且以.java的格式保存操作系统中,这些文件我们称之为源文件。
2、通过JDK中的javac.exe编译这些源文件形成.class类。
3、直接运行这些类或者部署在WEB容器中运行,得到输出结果。
这些过程是从宏观上面来观察的,了解这个肯定是不行的,我们需要真正来了解java是如何来编码和被解码的:
第一步:当我们用编辑器编写java源文件,程序文件在保存时会采用操作系统默认的编码格式(一般我们中文的操作系统采用的是GBK编码格式)形成一个.java文件。java源文件是采用操作系统默认支持的file.encoding编码格式保存的。下面代码可以查看系统的file.encoding参数值。
System.out.println(System.getProperty("file.encoding"));
第二步:当我们使用javac.exe编译我们的java文件时,JDK首先会确认它的编译参数encoding来确定源代码字符集,如果我们不指定该编译参数,JDK首先会获取操作系统默认的file.encoding参数,然后JDK就会把我们编写的java源程序从file.encoding编码格式转化为JAVA内部默认的UNICODE格式放入内存中。
第三步:JDK将上面编译好的且保存在内存中信息写入class文件中,形成.class文件。此时.class文件是Unicode编码的,也就是说我们常见的.class文件中的内容无论是中文字符还是英文字符,他们都已经转换为Unicode编码格式了。
在这一步中对对JSP源文件的处理方式有点儿不同:WEB容器调用JSP编译器,JSP编译器首先会查看JSP文件是否设置了文件编码格式,如果没有设置则JSP编译器会调用调用JDK采用默认的编码方式将JSP文件转化为临时的servlet类,然后再编译为.class文件并保持到临时文件夹中。
第四步:运行编译的类:在这里会存在一下几种情况
1、直接在console上运行。
2、JSP/Servlet类。
3、java类与数据库之间。
1:I/O操作
2:内存
3:数据库
4:javaWeb
InputStream为字节输入流的所有类的超类,Reader为读取字符流的抽象类。java读取文件的方式分为按字节流读取和按字符流读取,其中InputStream、Reader是这两种读取方式的超类。
按字节
我们一般都是使用InputStream.read()方法在数据流中读取字节(read()每次都只读取一个字节,效率非常慢,我们一般都是使用read(byte[
])),
然后保存在一个byte[]数组中,最后转换为String。在我们读取文件时,读取字节的编码取决于文件所使用的编码格式,而在转换为String过程中
也会涉及到编码的问题,如果两者之间的编码格式不同可能会出现问题。例如存在一个问题test.txt编码格式为UTF-8,那么通过字节流读取文件时所
获得的数据流编码格式就是UTF-8,而我们在转化成String过程中如果不指定编码格式,则默认使用系统编码格式(GBK)来解码操作,由于两者编
码格式不一致,那么在构造String过程肯定会产生乱码,如下:
File file = new File("C:\\test.txt");
InputStream input = new FileInputStream(file);
StringBuffer buffer = new StringBuffer();
byte[] bytes = new byte[1024];
for(int n ; (n = input.read(bytes))!=-1 ; ){
buffer.append(new String(bytes,0,n));
}
System.out.println(buffer);
输出结果:锘挎垜鏄?cm
test.txt中的内容为:我是 cm。
要想不出现乱码,在构造String过程中指定编码格式,使得编码解码时两者编码格式保持一致即可:buffer.append(new String(bytes,0,n,"UTF-8"));
字节&字符转换
字节转换为字符一定少不了InputStreamReader。API解释如下:InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset
读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。 每次调用 InputStreamReader 中
的一个 read() 方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足
当前读取操作所需的字节。API解释非常清楚,InputStreamReader在底层读取文件时仍然采用字节读取,读取字节后它需要根据一个指定的编码
格式来解析为字符,如果没有指定编码格式则采用系统默认编码格式。
String file = "C:\\test.txt";
String charset = "UTF-8";
// 写字符换转成字节流
FileOutputStream outputStream = new FileOutputStream(file);
OutputStreamWriter writer = new OutputStreamWriter(outputStream, charset);
try {
writer.write("我是 cm");
} finally {
writer.close();
}
// 读取字节转换成字符
FileInputStream inputStream = new FileInputStream(file);
InputStreamReader reader = new InputStreamReader(
inputStream, charset);
StringBuffer buffer = new StringBuffer();
char[] buf = new char[64];
int count = 0;
try {
while ((count = reader.read(buf)) != -1) {
buffer.append(buf, 0, count);
}
} finally {
reader.close();
}
System.out.println(buffer);
- javaWeb中的编码解码
请求
客户端想服务器发送请求无非就通过四中情况:
1、URL方式直接访问。
2、页面链接。
3、表单get提交
4、表单post提交
- 解决URL中文乱码问题
encodeURI
对整个URL进行编码,它采用的是UTF-8格式输出编码后的字符串。不过encodeURI除了ASCII编码外对于一些特殊的字符也不会进行编码如:! @ # $& * ( ) = : / ; ? + ‘。
encodeURIComponent()
把URI字符串采用UTF-8编码格式转化成escape格式的字符串。相对于encodeURI,encodeURIComponent会更加强大,它会对那些在encodeURI()中不被编码的符号(; / ? : @ & = + $ , #)统统会被编码。但是encodeURIComponent只会对URL的组成部分进行个别编码,而不用于对整个URL进行编码。对应解码函数方法decodeURIComponent。