JavaSE(2)16 IO流--字符流

IO流

字符流

为什么会出现字符流
  • 字符流的介绍
    • 由于字节流操作中文不是特别的方便,所以Java就提供字符流
    • 字符流 = 字节流 + 编码表
  • 中文的字节存储方式
    • 用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文,如何识别是中文的呢?
    • 汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数
  public static void main(String[] args) throws IOException {
        FileInputStream fileInputStream=new FileInputStream("BasicGrammar\\abc123.txt");
        FileOutputStream fileOutputStream=new FileOutputStream("BasicGrammar\\abc.txt");
//如果一次读一个字节 中文将出现乱码
//        int by;
//        while((by=fileInputStream.read())!=-1){
//            fileOutputStream.write((char)by);
//            System.out.println((char)by);
//        }
        byte [] bytes=new byte[1024];
        int len;
        while ((len=fileInputStream.read(bytes))!=-1){
            fileOutputStream.write(bytes,0,len);
            System.out.println(new String(bytes));
        }
    }
编码表
  • 基础知识:
    • 计算机中存储的信息都是用二进制数表示的,我们在屏幕上看到的英文、汉字是二进制转换后的结果
    • 按照某种规则,将字符存储在计算机中,称之为编码。反之,将存储在计算机中的二进制数按照某种规则解析出来,称之为解码
    • 按照A编码进行存储,必须按照A编码解析,这样才能显示正确的文本符,否则就会导致乱码现象。
  • 字符编码:就是一套自然语言的字符与二进制数之间的对应规则(A,65)
  • 字符集:
    • 是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等
    • 计算机要准确的存储和识别各种字符集符号,就需要进行字符编码,一套字符集必然至少有一套字符编码。常见字符集有ASCII字符集、GBXXX字符集、Unicode字符集等
  • 常见的字符集
    • lASCII:
      • 是基于拉丁字母的一套电脑编码系统,用于显示现代英语,主要包括控制字符(回车键、退格、换行键等)和可显示字符(英文大小写字符、阿拉伯数字和西文符号)
      • 基本的ASCII字符集,使用7位表示一个字符,共128字符。ASCII的扩展字符集使用8位表示一个字符,共256字符,方便支持欧洲常用字符。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等
    • GBK:最常用的中文码表。是在GB2312标准基础上的扩展规范,使用了双字节编码方案,共收录了21003个汉字,完全兼容GB2312标准,同时支持繁体汉字以及日韩汉字等
    • Unicode字符集:
      • UTF-8编码:可以用来表示Unicode标准中任意字符,它是电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。它使用一至四个字节为每个字符编码
      • 编码规则:
        • 128个US-ASCII字符,只需一个字节编码
        • 拉丁文等字符,需要二个字节编码
        • 大部分常用字(含中文),使用三个字节编码
        • 其他极少使用的Unicode辅助字符,使用四字节编码
  • 采用何种规则编码,就要采用对应规则解码,否则就会出现乱码
字符串中的编码解码问题
  • 编码
    在这里插入图片描述
  • 解码
    在这里插入图片描述
//编码、解码
    public static void main(String[] args) throws UnsupportedEncodingException {
        String str="中国";
        //编码操作
        byte[] bytes = str.getBytes();
        System.out.println(Arrays.toString(bytes));//[-28, -72, -83, -27, -101, -67]
        byte[] bytes1 = str.getBytes("utf-8");
        System.out.println(Arrays.toString(bytes1));//[-28, -72, -83, -27, -101, -67]
        byte[] bytes2 = str.getBytes("GBK");
        System.out.println(Arrays.toString(bytes2));//[-42, -48, -71, -6]
        //解码操作
        String s = new String(bytes);
        System.out.println(s);//中国
        String s1 = new String(bytes1,"utf-8");
        System.out.println(s1);//中国
        String s2 = new String(bytes2,"GBK");
        System.out.println(s2);//中国
    }
字符流中的编码解码问题
  • 字符流抽象基类
    • Reader:字符输入流的抽象类
    • Writer:字符输出流的抽象类
  • 字符流中和编码解码问题相关的两个
    • inputStreamReader:是从字节流到字符流的桥梁,它读取字节,并使用指定的编码将其解码为字符,它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
    • OutputStreamWriter:是从字符流到字节流的桥梁,是从字符流到字节流的桥梁,使用指定的编码将写入的字符编码为字节,它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
  • 构造方法
    在这里插入图片描述
public static void main(String[] args) throws IOException {
		Writer outputStreamReader=new OutputStreamWriter(new FileOutputStream("F:\\abc.txt"),"GBK");
		Reader inputStreamReader=new InputStreamReader(new FileInputStream("F:\\abc.txt"),"GBK");
		outputStreamReader.write("中国");
		一次读取一个字符数据
		int ch;
		while((ch=inputStreamReader.read())!=-1) {
			System.out.println((char)ch);
		}
		inputStreamReader.close();
		outputStreamReader.close();
	}
字符流写数据的5种方式

在这里插入图片描述

//字符流写数据的5种方式
			public static void main(String[] args) throws IOException {
			OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("F:\\phx.txt"));
			//方式一:每次写一个字符
			//		osw.write(97);
			//		osw.write(98);
			//		osw.write(99);
			//		//phx.txt:abc
			//		osw.close();
			//方式二:写入一个字符数组
			//		char[] chars= {'a','b','c','d'};
			//		osw.write(chars);
			//		//phx.txt:abcd
			//		osw.close();
			//方式三:写入字符数组的一部分
			//		char[] chars= {'a','b','c','d'};
			//		osw.write(chars,1,chars.length-1);
			//		//phx.txt:bcd
			//		osw.close();
			//方式四:写入字符串
			//		String str="Hello,World";
			//		osw.write(str);
			//		//phx.txt:Hello,World
			//		osw.close();
			//方式五:写一个字符串的一部分
			String str="Hello,Word";
			int len=str.length();
			//第一个5代表的是要获取的字符串的开始位置,第二个5表示从开始开始位置开始获取的字符个数
			osw.write(str,5,5);
			//phx.txt:,Word
			osw.close();
			}
字符流读数据的2种方式

在这里插入图片描述

	//字符流读数据的2种方式
	public static void main(String[] args) throws IOException {
		Reader reader=new InputStreamReader(new FileInputStream("F:\\phx.txt"),"utf-8");
		//方式一:一次读一个字符
//		int ch;
//		while((ch=reader.read())!=-1) {
//			System.out.print((char)ch+" ");//H e l l o , W o r d ! 你 好 
//		}
//		reader.close();
		//方式二:一次读取一个字符数组
		char[]chars=new char[1024];
		int len;
		while((len=reader.read(chars))!=-1) {
			System.out.println(new String(chars));//Hello,Word!你好
		}
		reader.close();
	}
字符流复制Java文件
	//根据数据源创建字符输入流对象
		Reader isr= new InputStreamReader(new FileInputStream("F:\\HelloServlet.java"));
		//根据目的地创建字符输出流对象
		Writer osw=new OutputStreamWriter(new FileOutputStream("F:\\phx.java"));
		//读写数据,复制文件
		//一次读写一个字符数据
//		int ch;
//		while((ch=isr.read())!=-1) {
//			osw.write(ch);
//		}
//		isr.close();
//		osw.close();
		int len;
		char[] chars=new char[1024];
		while((len=isr.read(chars))!=-1) {
			osw.write(chars, 0, len);
		}
		释放资源
		isr.close();
		osw.close();
	}
字符流复制Java文件改进版
public static void main(String[] args) throws IOException {
		//根据数据源创建字符输入流对象
		//Reader isr= new InputStreamReader(new FileInputStream("F:\\HelloServlet.java"));
		Reader fr=new FileReader("F:\\\\HelloServlet.java");
		//根据目的地创建字符输出流对象
		//Writer osw=new OutputStreamWriter(new FileOutputStream("F:\\phx.java"));
		Writer fw=new FileWriter("F:\\phx.java");
		//读写数据,复制文件
		//一次读写一个字符数据
//		int ch;
//		while((ch=isr.read())!=-1) {
//			osw.write(ch);
//		}
//		isr.close();
//		osw.close();
		int len;
		char[] chars=new char[1024];
		while((len=fr.read(chars))!=-1) {
			fw.write(chars, 0, len);
		}
		释放资源
		fr.close();
		fw.close();
	}
字符缓冲流
  • 字符缓冲流介绍
    • BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区大小,或者可以接受默认大小。默认值足够大,可用于大多数用途
    • BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小,或者可以使用默认大小。 默认值足够大,可用于大多数用途
  • 构造方法
    在这里插入图片描述
public static void main(String[] args) throws IOException {
		//字符缓冲流
		BufferedWriter bw=new BufferedWriter(new FileWriter("F:\\abc.txt"));
		BufferedReader br=new BufferedReader(new FileReader("F:\\abc.txt"));
		bw.write("Hello,\r\n");
		bw.write("你好");
		bw.close();//必须先关闭,否则后面不执行
		char []chars=new char[1024];
		int len;
		while((len=br.read(chars))!=-1) {
			System.out.print(new String(chars,0,len));
		}	
		br.close();
	}
字符缓冲流复制Java文件
//字符缓冲流复制Java文件
		BufferedWriter bw=new BufferedWriter(new FileWriter("F:\\phx.java"));
		BufferedReader br=new BufferedReader(new FileReader("F:\\HelloServlet.java"));
		char []chars=new char[1024];
		int len;
		while((len=br.read(chars))!=-1) {
			bw.write(chars);
		}	
		br.close();
		bw.close();
	}
字符缓冲流特有功能

在这里插入图片描述

public static void main(String[] args) throws IOException {
		//创建字符缓冲输出流
		BufferedWriter bw=new BufferedWriter(new FileWriter(new File("F:\\phx.txt")));
		//写数据
		for(int i=0;i<10;i++) {
			bw.write("hello world"+i);
			bw.newLine();
			bw.flush();
		}
		//释放资源
		bw.close();
		BufferedReader br=new BufferedReader(new FileReader("F:\\phx.txt"));
		String line;
		while((line=br.readLine())!=null) {
			System.out.println(line);
		}
		br.close();
	}
字符缓冲流特有功能复制Java文件
public static void main(String[] args) throws IOException {
		BufferedReader br=new BufferedReader(new FileReader("F:\\HelloServlet.java"));
		BufferedWriter bw=new BufferedWriter(new FileWriter("F:\\phx.java"));
		//读写数据,复制文件
		//使用字符缓冲流特有功能实现
		String line;
		while((line=br.readLine())!=null) {
			bw.write(line);
			bw.newLine();
			bw.flush();
		}
		br.close();
		bw.close();
	}

IO流小结

字节流

在这里插入图片描述
小结:字节流可以复制任意文件数据,有四种方式,一般采用字节缓冲流一次读写一个字节数组的方式。

字符流

在这里插入图片描述
小结:字符流只能复制文本数据,有5种方式,一般采用字符缓冲流的特有功能

案例

把ArrayList集合中的学生数据写入到文本文件,把文本文件中的数据读取到集合中,并遍历集合

public class Demo12 {
	public static void main(String[] args) throws IOException {
		List<Student> list=new ArrayList<>();
		Student stu1=new Student(1, "张三", 18, "男", "上海市浦东新区");
		Student stu2=new Student(1, "李四", 18, "男", "上海市徐汇区");
		Student stu3=new Student(1, "王五", 18, "男", "上海市普陀区");
		Student stu4=new Student(1, "小明", 18, "男", "上海市宝山区");
		list.add(stu1);
		list.add(stu2);
		list.add(stu3);
		list.add(stu4);
		BufferedWriter bw=new BufferedWriter(new FileWriter("F:\\phx.txt"));
		//通过for循环把集合中的学生写入文件
		for(Student stu:list) {
			bw.write(stu.toString());
			bw.newLine();
			bw.flush();
		}
		bw.close();
		BufferedReader br=new BufferedReader(new FileReader("F:\\phx.txt"));
		String line="";
		List<Student> students=new ArrayList<>();
		//获取文件中的每一行信息赋值给学生
		while((line=br.readLine())!=null) {
			String[] strs=line.split(",");
			Student stu=new Student(Integer.parseInt(strs[0]),strs[1],Integer.parseInt(strs[2]),strs[3],strs[4]);
			students.add(stu);
		}
		for(Student stu:students) {
			System.out.println(stu);
		}
		
	}

}

//学生实体类
public class Student {
	private int id;
	private String name;
	private int age;
	private String sex;
	private String address;
	
	public Student(int id, String name, int age, String sex, String address) {
		this.id = id;
		this.name = name;
		this.age = age;
		this.sex = sex;
		this.address = address;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	@Override
	public String toString() {
		return  id + "," + name + "," + age + "," + sex + "," + address ;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值