了解一下常见的字符编码
了解乱码产生原因
计算机所有的都是二进式形式,那么所有能够描述出的中文文字都是经过处理后的结果。在我们的计算机世界里所有的文字都是用编码来描述,例如最常见的编码是ASCII码
- GBK、GB2312:中文的国标编码,其中GBK包含简体中文和繁体中文两种,后面的只包含简体
- ISO8859-1:是国际编码,可以描述任何的文字信息;
- UNICODE:16进制编码
- UTF编码(UTF-8):融合了ISO8859-1和UNICODE编码的特点;(需要16进制的就用16进制,不需要传一个字符就完事了)
在以后的所有开发里面使用的都是UTF-8编码
==所谓的乱码就是我们编码和解码的字符集不统一。==如果想要知道现在系统的所有环境属性。
public static void main(String[] args) throws Exception {//正常工作一定要通过try catch处理
System.getProperties().list(System.out);
//列出系统当前的所有属性
}
public static void main(String[] args) throws Exception {//正常工作一定要通过try catch处理
// System.getProperties().list(System.out);
//列出系统当前的所有属性
File file = new File("/users/hong/hongs/firsttext.txt");
OutputStream output = new FileOutputStream(file);
output.write("中国人民万岁!".getBytes("ISO8859-1"));//有转码,非正常输出
output.write("中国人民万岁!".getBytes());//没有转码
output.close();
}
所谓乱码的本质就是编码集不统一。
总结
- 以后使用的所有代码都是UTF-8
- 乱码的本质是编码和解码不统一
内存流
当学习到AJAX和XML(JSON)应用的时候才会牵扯到此部分
可以使用内存流进行I/O操作
之前使用了文件操作流实现了针对文件数据的输入与输出操作,但是如果现在某一种应用需要进行I/O操作又不想产生文件的时候,就可以利用内存来实现输入和输出操作。
针对内存流,在java.io中提供了两组操作:
- 字节内存流:ByteArrayInputStream、ByteArrayOutputStream
- 字符内存流:CharArrayReader、CharArrayWriter
本次是以字节内存流操作为主,下面重点来看一下:ByteArrayInputStream、ByteArrayOutputStream的继承结构和构造方法
ByteArrayInputStream
表示将要操作的数据设置到输入流
ByteArrayOutputStream
从内存输出数据
以文件操作为例:
- 输出(OutputStream):程序-> OutputStream->文件;
- 输入(InputStream):程序<- InputStream<-文件;
以内存操作为例: - 输出(InputStream):程序->InputStream->内存;
- 输入(OutputStream):程序<-OutputStream<-内存;
实现一个小写字母转大写字母的操作
- 为了方便的实现字母的转大写的转化(避免不必要的字符也被转换)可以借助于Character类
public static void main(String[] args) throws Exception {//正常工作一定要通过try catch处理
String str = "Hello*World!";//要求被转换的字符串
//本次将通过内容操作流实现转换。先将数据保存在内存流里面,而后从里面取出每一个数据
InputStream input = new ByteArrayInputStream(str.getBytes());
//将要读取的数据设置到内存输入流之中,本次利用向上转型
//为了能够可以讲内存流中的数据输出,可以使用ByteArrayOutputStream()
OutputStream output = new ByteArrayOutputStream();
int temp = 0;//读取每一个字节数据
//经过此次循环之后,所有数据都保存在内存输出流对象之中
while((temp=input.read())!=-1)
{
output.write(Character.toUpperCase(temp));
}
System.out.println(output);
output.close();
input.close();
}
以上操作的代码里,所有的输入和输出流都发生了向上转型,向上转型的好处是可以得到操作模式的统一,但是千万不要忽略一个问题:每一个子类都有每一个子类自己的功能,在ByteArrayOutputStream
类中有一个自己的特殊方法:
可以将所有保存在内存中的字节数据转变成字节数组存在
利用这个ByteArrayOutputStream
可以实现多个文件同时读取。但这个方法是子类自己的扩充方法
public static void main(String[] args) throws Exception {//正常工作一定要通过try catch处理
File fileA = new File("/users/hong/hongs/hello/firsttext.txt");
File fileB = new File("/users/hong/hongs/firsttext.txt");
InputStream inputA = new FileInputStream(fileA);
InputStream inputB = new FileInputStream(fileB);
ByteArrayOutputStream output = new ByteArrayOutputStream();
int temp = 0;
while ((temp=inputA.read())!=-1)
{
output.write(temp);
}
while((temp=inputB.read())!=-1)
{
output.write(temp);
}
//现在将所有的内容都保存在了内存输出流里面,所有的内容变为字节数组取出
byte data[]= output.toByteArray();
output.close();
inputA.close();
inputB.close();
System.out.println(new String(data));
}
对于OutputStream和InputStream又有了新的输入和输出的位置,其中以ByteArrayOutputStream类最为好用。
总结
- 内存操作流短期内是不会使用到的
- 需要结合一些具体的案例才可以更好的掌握好此类的使用
- 发生了I/O操作,但是没有文件,所有的内容是以内存为终端的