在学校还是很自由的,可以自由的玩,上午打羽毛球下午还任性的去打,自由的学一些自己感兴趣的课外东西。珍惜现在的每一天吧。同时晚上关掉手机或将手机放在实验室会让时间变多,可以思考一下如何可以打好羽毛球、如何更好的学习Java、思考一下最近发生的事情,要让不玩手机成为习惯。好了,开始代码~~

       (1)字节流转换成字符流

      在【14】中看到这些代码,这也觉得太麻烦了吧,同时看到\r\n会I想到一些东西,



while((ch=in.read())!=-1){
			//在存储之前判断是否是换行标志
			if(ch=='\r')
				continue;
			if(ch=='\n'){  //一行结束,进行判断
				String temp = sb.toString();
				if("over".equals(temp))
					break;
				System.out.println(temp.toUpperCase());
				sb.delete(0, sb.length());
			}

想到在【9】中MyBufferedReader自定义缓冲区中的代码,里面是用来重新写readLine的方法,那么我们就可以直接使用readLine方法,但一个问题是在字节流InputStream里面是没有这个方法的,这个方法只有字符流BufferedReader里面有。但是字符流装饰不了字节流,所以就需要转换。

        所以我们就在字符流子类对象里面找到了InputStreamReader(字节流+字符流),这就是字节和字符转换方式。

InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。 每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。其实这个技术在前面判断季节小测试中已经用到。代码如下:

public static void main(String[] args) throws IOException {
		/*
		 * 为了使用readLine利用InputStreamReader将字节流转换为字符流
		 */
		
		//字节流
		InputStream in = System.in;
		
		//将字节流装换为字符流,一旦转换成字符流,遇到中文就可以只读一次。因为用底层的字节流
		//读取两次后返回一个中文
		InputStreamReader isr = new InputStreamReader(in);		
		
		//字符流
		BufferedReader bufr = new BufferedReader(isr);
		String line = null;
		while((line=bufr.readLine())!=null){
			if("over".equals(line)){
				break;
			}
			else System.out.println(line.toUpperCase());
		}		
	
	}



        那么当将字节流转换为字符流后遇到中文就可以只读一次,因为用底层的字节流读取两次后返回一个中文。演示如下,当用字符流读取一个汉子时

InputStream in = System.in;
		
		//将字节流装换为字符流,一旦转换成字符流,遇到中文就可以只读一次。因为用底层的字节流
		//读取两次后返回一个中文
		
		int ch = in.read();
		System.out.println(ch);
		int ch1 = in.read();
		System.out.println(ch1);

会出现两个字节。

java 字节转字符串 GBK_IO

然而,使用转换后的字符流的时候,代码如下:

InputStream in = System.in;
		InputStreamReader isr = new InputStreamReader(in);		
		int ch = isr.read();
		System.out.println(ch);

会出现这样的结果:

java 字节转字符串 GBK_IO_02

     (2)字符流转换成字节流OutputStreamWriter是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。 每次调用 write() 方法都会导致在给定字符(或字符集)上调用编码转换器。在写入底层输出流之前,得到的这些字节将在缓冲区中累积。可以指定此缓冲区的大小,不过,默认的缓冲区对多数用途来说已足够大。注意,传递给 write() 方法的字符没有缓冲。

       在下面的程序中Systen.out是标准的字节流输出,现在将其用OutputStreamWriter封装一下,再用BufferedWriter装饰一下,利用writer用字符流方式输出。代码如下:

InputStream in = System.in;
		
		//将字节流装换为字符流,一旦转换成字符流,遇到中文就可以只读一次。因为用底层的字节流
		//读取两次后返回一个中文
		InputStreamReader isr = new InputStreamReader(in);
				
		//这个就是字节流输出
		OutputStream out = System.out;
		OutputStreamWriter outw = new OutputStreamWriter(out);
		BufferedWriter bufw = new BufferedWriter(outw);
		
		//字符流
		BufferedReader bufr = new BufferedReader(isr);
		String line = null;
		while((line=bufr.readLine())!=null){
			if("over".equals(line))
				break;			
//			else System.out.println(line.toUpperCase());  //这是标准输出流,换一种写法
			//将字节流转换为字符流,显示在控制台上
			bufw.write(line.toUpperCase());
			bufw.newLine();	
			bufw.flush();			
		}



当然这写代码都可以按API里的例子简化写。

BufferedReader in
   = new BufferedReader(new InputStreamReader(System.in));
Writer out
   = new BufferedWriter(new OutputStreamWriter(System.out));