欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java IO之字符流

程序员文章站 2024-03-04 15:23:53
...

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输入流

            java IO之字符流

        3.1.2输出流

                java IO之字符流

    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();
				}
			}
		}
		
	}

}