java IO之字符流

1、字节流与字符流的区别

    字节流处理单元为1个字节,操作字节和字节数组,而字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串。所以字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的,所以它对多国语言支持性比较好!如果是音频文件、图片、歌曲,就用字节流好点,如果是关系到中文(文本)的,用字符流好点.

代码说明(以读取文件E:\tesst\test.txt 内容为例 test.txt)

字节流

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class ReadTest {
	
	//1、定义缓冲区大小可以是1024的整数倍
	private static final int SIZE = 1024;
	
	public static void main(String[] args) throws IOException {
		
		//创建流
		File file = new File("E:\\test\\test.txt");
		FileInputStream fis = new FileInputStream(file);
		
		byte []buf = new byte[SIZE];
		int len = fis.read(buf);
		
		String result = new String(buf, 0, len);// 将字节数组转成字符串,而且是按照默认的编码表(GBK)进行解码。
		System.out.println(result);
		
		//关闭资源
		fis.close();
			
	}
}

    字节流String类的String(byte[] bytes, int offset, int length)构造方法是通过使用平台的默认字符集(即GBK码表)解码指定的byte子数组,构造一个新的String

字符流

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class ReadTest {

	public static void main(String[] args) throws IOException{
		
		// 1、创建字节流
		File file = new File("E:\\test\\test.txt");
		FileInputStream fis = new FileInputStream(file);
		
		// 2、建立字节向字符转换流。
		InputStreamReader isr = new InputStreamReader(fis);
		
		int result = isr.read();
		System.out.println((char)result);
		int result2 = isr.read();
		System.out.println((char)result2);
		int result3 = isr.read();
		System.out.println(result3);
		
		//3、关闭资源
		fis.close();
		isr.close();
	}

}

2、编码表

    2.1编码表的由来

        计算机只能识别二进制数据,早期由来是电信号来表示,为了方便应用计算机,让它可以识别各个国家的文字,就将各个国家的文字用数字来表示,并一一对应,形成一张表,这就是编码表。

    2.2常见的编码表

        常见的编码表有:  

  • ASCII:美国标准信息交换码,用一个字节的7位可以表示。
  • ISO8859-1:拉丁码表或欧洲码表,用一个字节的8位表示。
  • GB2312:中国的中文编码表。
  • GBK:中国的中文编码表升级,融合了更多的中文文字符号。
  • Unicode:国际标准码,融合了多种文字,所有文字都用两个字节来表示,Java语言使用的就是Unicode。
  • UTF-8:最多用三个字节来表示一个字符。

    2.3编码与解码

        所谓编码就是字符串变成字节数组(String→byte[]),代表方法为 str.getBytes(charsetName);而所谓解码就是字节数组变成字符串(byte[]→String),代表方法为 new String(byte[], charsetName);。关于编码与解码,有一个结论,即由UTF-8编码,自然要通过UTF-8来解码;同理,由GBK来编码,自然也要通过GBK来解码,否则会出现乱码。

3、字符流

    3.1字符流类的层次结构

        3.1.1输入流

            

        3.1.2输出流

                

    3.2常用的字符流

        由上图可以看出比较常用的字符流类有 InputStreamReader、OutputStreamWriter、FileReader、FileWriter、

BufferedReader、BufferedWriter、PrintWrite

       3.2.1转换流InputStreamReader\OutputStreamWriter               

            InputStreamReader 将字节流转换为字符流。是字节流通向字符流的桥梁。OutputStreamWriter 将字节流转换为字符流。是字节流通向字符流的桥梁。如果不指定字符集编码,该解码过程将使用平台默认的字符编码,如:GBK。

            例  在文件中写入数据然后读出数据最后打印读出的数据

package com.xyq.read;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class StreamConverter {

	public static void main(String[] args)throws IOException {
		writeTest();
		readTest();
	}
	
	public static void writeTest()throws IOException{
		
		//1、创建流
		File file = new File("tempFile\\test.txt");
		FileOutputStream fos = new FileOutputStream(file);
		OutputStreamWriter osw = new OutputStreamWriter(fos, "utf-8");
		
		//2、写出数据
		osw.write("世界你好!");
		
		//3、关闭资源
		osw.close();
		fos.close();
	}
	
	public static void readTest()throws IOException{
		
		//1、创建流
		File file = new File("tempFile\\test.txt");
		FileInputStream fis = new FileInputStream(file);
		InputStreamReader isr = new InputStreamReader(fis, "utf-8");
		
		//2、读出入数据
		char []cbuf = new char[1024];
		int len = isr.read(cbuf);
		String result = new String(cbuf, 0, len);
		System.out.println(result);
		
		//3、关闭资源
		isr.close();
		fis.close();
	}
	
}

        3.2.2转换流的子类,用于操作字符文件的便捷类FileReader\FileWriter

                它俩是用于操作字符文件的便捷类,但是它俩有局限性,只能操作字符文件,而且是默认编码,如果不操作字符文件,而且编码不是默认的,需要使用转换流。
                例  在硬盘上,创建一个文件并写入一些文字数据,然后读取文字数据,最后打印读取的文字数据
                
package com.xyq.read;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class SubTransStreamTest {

	public static void main(String[] args)throws IOException {
		writeTest();
		readTest();
	}
	
	public static void writeTest() throws IOException{
		
		//1、创建流
		File file = new File("tempFile\\test.txt");
		FileWriter fw = new FileWriter(file);
		
		//2、写出数据
		fw.write("世界你好!");
		
		//3、关闭资源
		fw.close();
	}
	public static void readTest()throws IOException{
		
		//1、创建流
		File file = new File("tempFile\\test.txt");
		FileReader fr = new FileReader(file);
		
		//2、读入数据
		char []cbuf = new char[1024];
		int len = fr.read(cbuf);
		String result = new String(cbuf, 0, len);
		System.out.println(result);
		
		//3、关闭资源
		fr.close();
	}

}

        3.2.3缓冲流BufferedReader\BufferedWriter

                bufferedWriter  该缓冲区中提供了一个跨平台的换行符:newLine()。
                bufferedReader   该缓冲区提供了一个一次读一行的方法:readLine(),方便于对文本数据的获取,当返回null时,表示读 取到文件末尾。
                注意:readLine()方法返回的时候只返回回车符之前的数据内容,并不返回回车符(行终止符)。
                例  在硬盘上,创建一个文件并写入一些文字数据,然后读取文字数据,最后打印读取的文字数据
                
package com.xyq.read;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class CharBufferedStreamTest {

	public static void main(String[] args)throws IOException {
		writeTest();
		readTest();
	}
	
	public static void writeTest()throws IOException{
		
		//1、创建流
		File file = new File("tempFile\\test.txt");
		FileOutputStream fos = new FileOutputStream(file);
		OutputStreamWriter osw = new OutputStreamWriter(fos, "utf-8");
		BufferedWriter bw = new BufferedWriter(osw);
		
		//2、写出数据
		for(int i=0; i<3; i++){
			bw.write(i + "世界你好!");
			bw.newLine();
			bw.flush();
		}
		
		//3、关闭资源
		bw.close();
		osw.close();
		fos.close();
	}
	
	
	public static void readTest()throws IOException{
		
		//1、创建流
		File file = new File("tempFile\\test.txt");
		FileInputStream fis = new FileInputStream(file);
		InputStreamReader isr = new InputStreamReader(fis, "utf-8");
		BufferedReader br = new BufferedReader(isr);
		
		//2、读入数据
		String result = "";
		while((result = br.readLine()) != null){
			System.out.println(result);
		}
		
		//3、关闭资源
		br.close();
		isr.close();
		fis.close();
	}

}

        3.2.4PrintWrite

                向文本输出流打印对象的格式化表示形式。此类实现在 PrintStream 中的所有 print 方法。它不包含用于写入原始字节的方法,对于这些字节,程序应该使用未编码的字节流进行写入。

                与 PrintStream 类不同,如果启用了自动刷新,则只有在调用 println、printf 或 format 的其中一个方法时才可能完成此操作,而不是每当正好输出换行符时才完成。这些方法使用平台自有的行分隔符概念,而不是换行符。

                此类中的方法不会抛出 I/O 异常,尽管其某些构造方法可能抛出异常。客户端可能会查询调用 checkError() 是否出现错误。

                printWrint常用API
package com.xyq.read;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class PrintStreamTest {

	public static void main(String[] args) {
//		printTest();
		printAutoFlshTest();
		printControllerTest();
	}
	

	/**
	 * 使用打印流写入到文件
	 */
	public static void printTest(){
		
		File file = null;
		PrintWriter out = null;
		
		try {
			//1、创建流
			file = new File("tempFile\\test.txt");
			
			//2、实例化printWriter打印对象,并开启自动刷新功能
			out = new PrintWriter(file);
			
			//3、写入数据
			out.println("你好 世界 !");
			out.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			//4.关闭资源
			if(out != null){
				try {
					out.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * 使用自动刷新的打印流写入到文件
	 */
	public static void printAutoFlshTest(){
		
		File file = null;
		FileWriter fw = null;
		PrintWriter out = null;
		
		try {
			//1、创建流
			file = new File("tempFile\\test.txt");
			fw = new FileWriter(file);
			
			//2、实例化printWriter打印对象,并开启自动刷新功能
			out = new PrintWriter(fw, true);
			
			//3、写入数据
			//将数据写入到文件
			//因为开启了自动刷新功能,所以println相当于以下执行了以下方法
			//printWriter.write(String string);写入字符
			//printWriter.newLine(); 换行
			//printWriter.flsh(); 冲刷数据
			
			out.println("我开启了PrintWriter的自动缓冲刷新功能");
			out.println("我将要被写入到文件中,等待被读取");
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			//4.关闭资源
			if(out != null){
				try {
					out.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			if(fw != null){
				try {
					fw.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * 读取文件内容,使用PrintWriter打印到控制台
	 */
	public static void printControllerTest(){
		
		File file = null;
		FileReader fr = null;
		BufferedReader in = null;
		PrintWriter out = null;
		
		try {
			//1、创建流
			file = new File("tempFile\\test.txt");
			fr = new FileReader(file);
			in = new BufferedReader(fr);
			
			//2、实例化printWriter打印对象,并开启自动刷新功能
			out = new PrintWriter(System.out, true);
			
			//3、输出数据
			String result = "";
			while((result = in.readLine()) != null){
				
				 //将数据输出到控制台
			     //因为开启了自动刷新功能,所以println相当于以下执行了以下方法
			     //printWriter.write(String string);写入字符
			     //printWriter.newLine(); 换行
			     //printWriter.flsh(); 冲刷数据
				out.println(result);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			//4.关闭资源
			if(out != null){
				try {
					out.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			if(in != null){
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(fr != null){
				try {
					fr.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}

}

4、System类对IO的支持

System.out对应的是标准输出设备,即控制台;System.in对应的是标准输入设备,即键盘。
例 通过键盘录入数据,当录入一行数据后,就将该行数据进行打印,如果录入的数据是over,那么录入停止
package com.xyq.read;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class SystemIOTest {

	public static void main(String[] args) {
		
		BufferedReader bufr = null;
		BufferedWriter bufw = null;
		
		try {
			//1、读取键盘录入
			System.out.println("请输入你的想要输入的信息");
			bufr = new BufferedReader(new InputStreamReader(System.in));
			
			//2、创建输出流
			bufw = new BufferedWriter(new OutputStreamWriter(System.out));
			
			//3、输出读取到的信息
			String result = "";
			while((result = bufr.readLine()) != null){
				if("over".equals(result)){
					System.out.println("输入结束");
					break;
				}
				bufw.write(result);//写出数据
				bufw.newLine();//换行
				bufw.flush();//冲刷
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			//4、关闭资源
			if(bufw != null){
				try {
					bufw.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(bufr != null){
				try {
					bufr.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
	}

}



猜你喜欢

转载自blog.csdn.net/strong997/article/details/79949928