转换流(将字节流转换为字符流)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fighting123678/article/details/84259899

1、将字节流转换为字符流

(1)名称是前面四种抽象类的组合

(2)功能都是将字节流转换成字符流,但是没有将字符流转换成字节流的类,因为,已经获得了字符流,根本没有必要转换成字节流

(3)InputStreamReader是将InputStream中的字节转换成字符

OutputStreamWriter是将OutputStream中的字节转换成字符

(4)InputStreamReader和OutputStreamWriter两个类可以指定编码集合

(5)为什么要指定编码集合呢?

因为将字节转换成字符,读到程序中的时候,java程序在内存中的字符都是Unicode编码的但是从文件中读取的内容有自己的编码格式,可能是jbk编码,可能是ISO8859_1编码,还有可能是ASCILL编码,编码不同,所以要根据已有编码转换成Unicode编码,因此可以指定这些字符到底是什么编码格式的,但是如果指定编码格式错误的话,会出现乱码问题。

(6)怎么会出现乱码问题呢?

如果要将自己的编码转换成Unicode编码字符的话,要先确定原始字符到底是什么类型的编码,如果指定原始字符格式错误的话,会出现乱码问题。


2、实例1:TestTransform

—对TestFileInputStream的修改,可以读取文中字符(TestTileInputStream.java源代码文件中有字符、中文、英文,但是是因为按照字节来读的,读出来之后,很多中文都是乱码的,我们知道可以通过FileReader来读,同时也可以使用InputStreamReader来读)

import java.io.*;

/*对TestFileInputStream的修改,可以读取文中字符*/
public class TestTransform 
{
	public static void main(String[] args) 
	{
		int b=0;
		InputStreamReader isr=null;
		try
		{
			isr=new InputStreamReader(new FileInputStream("TestTileInputStream.java"));
			//通过InputStreamReader读取FileInputStream中读取的TestTileInputStream.java中的字符
			long num=0;
			while((b=isr.read())!=-1)
			{
				System.out.print((char)b);
				num++;
			}
			System.out.println("共读取了"+num+"个字符");
		}
		catch(FileNotFoundException e)
		{
			System.out.println("找不到指定文件");
		}
		catch(IOException e1)
		{
			System.out.println("文件读取错误");
		}
		finally
		{
			try
			{
				isr.close();
			}
			catch(IOException e)
			{
				e.printStackTrace();
			}
		}
		System.exit(-1);
	}
}

最终正确地读取了805个字符,与字节数859不同,805个字符的字节数更多


2、实例2:TestTransform

功能:分别以中文Windows默认的GBK和ISO8859_1编码形式往文件中写入字符串

import java.io.*;

/*功能:分别以中文Windows默认的GBK和ISO8859_1编码形式往文件中写入字符串*/

public class TestTransFormEncoding {
	public static void main(String[] args) 
	{
		try
		{
			OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("transform1.txt"));
			//通过FileOutputStream文件输出流,往transform1.txt中写数据
			osw.write("计算机学院");
			osw.write("SUN Java");
			System.out.println(osw.getEncoding());//写入的时候没有指定编码格式,那么就采用中文Window默认编码GBK
			osw.close();
			
			//FileOutputStream构造方法第二个参数的含义,是否追加
			osw=new OutputStreamWriter(new FileOutputStream("transform1.txt",true),"ISO8859_1");
			/*这里用FileOutputStream的重载方法,形参加了个true
			 * 这里本来默认是false,每次写的时候,会覆盖原来文件的内容
			 * 但是加了true,意思是保留原有文件内容,并且在原有文件的尾部追加新的内容
			 * 编码格式改成IS08859_1,指的是英文字符,没有中文字符串
			 * lantin-1
			 * */
			osw.write("山东科技大学");//上面指定的编码格式中,没有文字字符串
			osw.write("C#");
			System.out.println(osw.getEncoding());
			osw.close();
		}
		catch(IOException e)
		{
			e.printStackTrace();
		}
	}
}

第一次写的时候没有问题,第二次写的时候C#没有问题,但是“计算机学院”出现了问题,因为ISO8859_1格式中无法解码中文


3、实例3:KeyboardInput

功能:实现键盘输入功能,类似于现在的Scanner

import java.io.*;

public class KeyboardInput 
{
	public static void main(String[] args)
	{
		String s;
		InputStreamReader isr=new InputStreamReader(System.in);
		/*
		 * 本来应该套一个InputStream,但是套了System.in
		 * 所以System.in也是InputStream类型的
		 * 所以可以传给InputStreamReader
		 * InputStreamReader套接了控制台键盘输入
		 * System.in读入的是字节,InputStreamReader转换成了字符
		 * InputStreamReader只能一个字符一个字符地读,比较麻烦,所以又套接了一个BufferedReader
		 * */
		BufferedReader br=new BufferedReader(isr);//BufferedReader的特点,能一次读取一行
		
		System.out.println("Unix:Type ctrl-d or cril-c to exit."+"\nWindows:Type ctrl-z to exit");
		try
		{
			//用Ctrl+z来结束
			while((s=br.readLine())!=null)
			{
				System.out.println("Read: "+s);//输入一行,打印一行
			}
		}
		catch(IOException e)
		{
			e.printStackTrace();
		}
		finally
		{
			try
			{
				br.close();
			}
			catch(IOException e)
			{
				e.printStackTrace();
			}
		}
	}
}

处理流怎么工作的呢?

最终打印结果

猜你喜欢

转载自blog.csdn.net/fighting123678/article/details/84259899