IO流——字符流

字节流读取字符的问题

通过以下程序读取带有中文的文件

public class CharStreamDemo {
	public static void main(String[] args) throws IOException {
		//给文件中写中文
		writeCNText();
		//读取文件中的中文
		readCNText();
	}	
	//读取中文
	public static void readCNText() throws IOException {
		FileInputStream fis = new FileInputStream("c:\\cn.txt");
		int ch = 0;
		while((ch = fis.read())!=-1){
			System.out.println(ch);
		}
	}
	//写中文
	public static void writeCNText() throws IOException {
		FileOutputStream fos = new FileOutputStream("c:\\cn.txt");
		fos.write("a欢迎你".getBytes());
		fos.close();
	}
}

上述程序在读取含义中文的文件时,我们并没有看到具体的中文,而是看到一些数字。要解决这个问题,就必须研究字符的编码过程。

字符编码表

编码表,其实就是生活中的字符和计算机二进制的对应关系表

1、ascII: 一个字节中的7位就可以表示。对应的字节都是正数。0-xxxxxxx

2、iso-8859-1:拉丁码表 latin,用了一个字节用的8位。1-xxxxxxx  负数。

3、GB2312:简体中文码表。包含6000-7000中文和符号。用两个字节表示。两个字节第一个字节是负数,第二个字节可能是正数

4、GBK:目前最常用的中文码表,2万的中文和符号。用两个字节表示,其中的一部分文字,第一个字节开头是1,第二字节开头是0

5、GB18030:最新的中文码表,目前还没有正式使用。

6、unicode:国际标准码表:无论是什么文字,都用两个字节存储。

        Java中的char类型用的就是这个码表。char c = 'a';占两个字节。

        Java中的字符串是按照系统默认码表来解析的。简体中文版 字符串默认的码表是GBK。

7、UTF-8:基于unicode,一个字节就可以存储数据,不要用两个字节存储,而且这个码表更加的标准化,在每一个字节头加入了编码信息(后期到api中查找)。

能识别中文的码表:GBK、UTF-8;正因为识别中文码表不唯一,涉及到了编码解码问题。

对于我们开发而言;常见的编码 GBK  UTF-8  ISO-8859-1

文字--->(数字) :编码。 “abc”.getBytes()  byte[]

(数字)--->文字  : 解码。 byte[] b={97,98,99}  new String(b)

字符输入流Reader    上面的程序读取拥有中文的文件时,使用的字节流在读取,那么读取到的都是一个一个的字节,只要把这些字节去查阅对应的编码表,就能得到与之对应的字符。API中已经提供了读取相应字符的功能流对象,Reader,读取字符流的抽象超类。

包含的方法有:

    read():读取单个字符

    read(char[] cbuf):将字符读入数组

FileReader类    用来读取字符文件的便捷类,此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当的。

构造方法:

1.使用FileReader读取包含中文的文件

public class CharStreamDemo {
	public static void main(String[] args) throws IOException {
		//给文件中写中文
		writeCNText();
		//读取文件中的中文
		readCNText();
	}	
	//读取中文
	public static void readCNText() throws IOException {
		FileReader fr = new FileReader("D:\\test\\cn.txt");
		int ch = 0;
		while((ch = fr.read())!=-1){
			//输出的字符对应的编码值
			System.out.println(ch);
			//输出字符本身
			System.out.println((char)ch);
		}
	}
	//写中文
	public static void writeCNText() throws IOException {
		FileOutputStream fos = new FileOutputStream("D:\\test\\cn.txt");
		fos.write("a欢迎你".getBytes());
		fos.close();
	}
}

字符输出流Writer    Writer是写入字符流的抽象类,其中描述了相应的写的动作:

    write(char[] cbuf):写入字符数组

    write(char[] cbuf, int off, int len):写入字符数组的某一部分

    write(int c):写入单个字符

    write(String str):写入字符串

    write(String str, int off, int len):写入字符串的某一部分

FileWrite类    用来写入字符文件的便捷类,此类的构造方法假定more字符编码和默认字符缓冲区大小都是可接受的。

构造方法:

1.FileWrite写入中文到文件中(先进行流的刷新,再进行流的关闭)

public class FileWriterDemo {
	public static void main(String[] args) throws IOException {
		//演示FileWriter 用于操作文件的便捷类。
		FileWriter fw = new FileWriter("d:\\text\\fw.txt");
		fw.write("你好谢谢再见");//这些文字都要先编码。都写入到了流的缓冲区中。
		fw.flush();
		fw.close();
	}
}

复制文本文件

代码如下:

public class CopyTextFileTest {
	public static void main(String[] args) throws IOException {
		copyTextFile();
	}
	public static void copyTextFile() throws IOException {
		//1,明确源和目的。
		FileReader fr = new FileReader("c:\\cn.txt");
		FileWriter fw = new FileWriter("c:\\copy.txt");
		//2,为了提高效率。自定义缓冲区数组。字符数组。
		char[] buf = new char[1024];
		int len = 0;
		while((len=fr.read(buf))!=-1){
			fw.write(buf,0,len);
		}
		//3,关闭资源。
		fw.close();
		fr.close();
	}
}

猜你喜欢

转载自blog.csdn.net/qq_41787619/article/details/80172010