字节缓冲区流/转换流/字符流/字符缓冲区流

本文详细探讨了Java中的字节缓冲区流、转换流、字符流和字符缓冲区流。从概念介绍到实际操作,包括不同流的复制效率测试、编码解码问题、流的使用方式以及字符流的练习,如文件复制、对象存储和读取等应用场景。
摘要由CSDN通过智能技术生成

一、字节缓冲区流的概述和使用

 缓冲流的作用是什么?

        为了提高IO流的读写效率

 缓冲流使用的是哪两个流对象?

        字节缓冲流:
            BufferedInputStream        : 输入
                 常见成员方法:   
                             intread()  : 一次读取一个字节
                              intread(byte[] bys) : 一次读取一个字节数组
            BufferedOutputStream    : 输出
                 常见成员方法:
                            write(inti)    : 写出单个字节
                             write(byte[]bys)    : 写出一个字节数组
                              write(byte[]bys, int off, int len) : 写出字节数组的一部分        

真正与文件产生关联的是那个流对象?

        FileInputStream, FileOutputStream

                 因为缓冲流仅仅是对普通字节流的一个包装.

二、字节流四种方式复制AVI并测试效率

 基本字节流一次读写一个字节            共耗时:50233毫秒
 缓冲字节流一次读写一个字节            共耗时:197毫秒
 缓冲字节流一次读写一个字节数组        共耗时:30毫秒
 基本字节流一次读写一个字节数组        共耗时:79毫秒

三、转换流出现的原因

 为什么要有转换流?
        A. 可以根据指定的编码表去读写字符            ->解决中文乱码问题(他是字符流的一种)
        B. 可以将字节流转换为字符流进行操作         ->可以对于纯文本文件的操作, 变得更加方便.   
     细节:
        GBK: 一个中文占用2个字节
        UTF-8: 一个中文占用3个字节
         非中文字符 : 占用1个字节      
         注意: 一般来说, 中文的字符, 都是以负数的字节进行存储.
                 但是也有一种现象, 第一个字节是负数,第二个字节是正数.
                 无论是怎样的编码表怎样的排列方式, 第一个字节肯定是负数.

四、编码表概述和常见编码表

 编码表:
         由字符及其对应的数据组成的一张表
        ASCII:
            ‘a’    97
            ‘A’    65
            ‘0’    48
 常见的编码表:
        ASCII: 美国标准信息交换码, 用一个字节的7位表示数据
        ISO-8859-1: 欧洲码表, 用一个字节的8位表示数据, 兼容ASCII
        GB2312: 中文码表, 兼容ASCII
        -----------------------------------------------------------
        GBK : 中文码表的升级版, 融合了更多的中文文字符号, 兼容ASCII
        UTF-8: 是一种可变长度的字符编码, 用1-3个字节表示数据, 又称为万国码, 兼容ASCII
                 用在网页上可以统一页面中的中文简体繁体和其他语言的显示.
乱码问题的产生:
        1. 使用字节流读取数据, 拼接的时候出现问题.
        2. 使用不同的编码表进行读写数据

五、String类中的编码和解码问题

 编码
     把看得懂的变成看不懂的
    public byte[] getBytes(StringcharsetName) throws UnsupportedEncodingException
     使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。 
        getByte(): 根据平台默认字符集进行编码
            Strings = " 你好";
            //[-60, -29, -70, -61]
            byte[]bys = s.getBytes()
        getByte(StringchatsetName) : 根据传入的编码表, 进行编码
            Stringss = " 你好";
            byte[]byse = ss.getBytes("utf-8");
            //[-28, -67, -96, -27, -91, -67]
 解码
     把看不懂的变成看得懂的
    public String(byte[] bytes,String charsetName)
     通过使用指定的 charset解码指定的 byte 数组,构造一个新的 String。
     重点强调 :  编码和解码的方式需要一致
 String类中编码和解码的方法
     编码: 
         getBytes();            --> 按照平台默认码表编码
         getBytes("UTF-8")        --> 按照指定的编码表进行编码
     解码:
        newString(byte[] bys);         根据平台默认编码表, 进行解码
        newString(byte[] bys, String charsetname); 根据传入的编码表, 进行解码
        Stringss = new String(bys,"UTF-8")    --> 根据传入的字节数组和字符集解码

六、转换流中的编码和解码问题

 转换流的构造方法
   OutputStreamWriter 字符输出流
      publicOutputStreamWriter(OutputStream out)
               根据默认编码把字节流的数据转换为字符流
      publicOutputStreamWriter(OutputStream out,String charsetName)
               根据指定编码把字节流数据转换为字符流
   InputStreamReader 字符输入流
      publicInputStreamReader(InputStream in)
               用默认的编码读数据
      publicInputStreamReader(InputStream in,String charsetName)
     需求: 以UTF-8编码的格式写出 “你好”到文件中, 并将数据正确的读取出来打印在控制台
     分析:
     第一步: 创建OutputStreamWriter关联文件, 并在构造方法中指定编码表
     第二步: 调用writer方法写出字符串
     第三步: 创建InputStreamReader关联文件, 并在构造方法中指定码表进行读取

    第四部: 调用read方法读取数据, 打印在控制台

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo01_Buffer {
	public static void main(String[] args) throws IOException {
		method01();
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy2.txt"));
		int i = 0;
		while((i = bis.read())!=-1){
			bos.write(i);
		}
		bis.close();
		bos.close();
	}
	private static void method01() throws FileNotFoundException, IOException {
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.txt"));
		byte[] bytes = new byte[2048];
		int len = 0;
		while((len = bis.read(bytes)) != -1){
			bos.write(bytes, 0, len);
		}
		bis.close();
		bos.close();
	}
	
}

七、OutputStreamWriter写数据的5种方式

 public void write(int c):写一个字符
 public void write(char[] cbuf):写一个字符数组
 public void write(char[] cbuf,intoff,int len):写一个字符数组的一部分
 public void write(String str):写一个字符串
 public void write(String str,int off,intlen):写一个字符串的一部分

八、InputStreamReader读数据的2种方式

 public int read():一次读取一个字符
 public int read(char[] cbuf):一次读取一个字符数组

九、字符流的练习之复制Java文件

 需求:把当前项目目录下的StringDemo.java内容复制到当前项目目录下的Copy.java中
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Demo02_FileRw {
	public static void main(String[] args) throws IOException {
		FileReader fr = new FileReader("a.txt");
		FileWriter fw = new FileWriter("b.txt");
		char[] c = new char[2048];
		int len;
		while ((len = fr.read(c)) != -1) {
			fw.write(new String(c, 0, len));
		}
		fr.close();
		fw.close();
	}
}

十、字符流的练习之复制Java文件改进版

 flush和close方法的区别
     总结:
        flush:     用于将缓冲区中的数据刷出到文件中.
                 调用完毕后, 可以继续写出数据.
        close:   用于关闭流释放资源的, 但是如果关闭的是字符流, 那么会将缓冲区中的数据刷出到文件, 然后再进行关闭.
                colse 方法调用结束, 不能再次写出数据
     字符输出流在写出数据的时候, 如果没有调用close方法或者是flush方法的话,那么数据将不会写出到目标文件中

十一、字符缓冲区流的概述和使用

 字符缓冲流使用的是哪两个类?
     总结:
        1. 输入: BufferedReader
        2. 输出: BufferedWriter

十二、字符缓冲区流的特殊功能

 readLine()方法的作用是?
 newLine()方法的作用是?
     总结:
        1. 一次读取一行字符串, 但是不会读取到回车换行符, 文件的末尾结束标记为null
        2. 用于写出回车换行, 但是具有跨平台性

十三、字符缓冲区流的特殊功能复制Java文件

    注意: readLine方法在读取的时候,不会读取到回车换行符

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Demo03_Line {
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new FileReader("a.txt"));
		BufferedWriter bw = new BufferedWriter(new FileWriter("c.txt"));
		String line;
		while((line = br.readLine()) != null){
			bw.write(line);
			bw.newLine();
		}
		br.close();
		bw.close();
	}
}

十四、字符流的练习之5种方式复制文本文件

 基本字符流一次读写一个字符
 基本字符流一次读写一个字符数组
 缓冲字符流一次读写一个字符
 缓冲字符流一次读写一个字符数组
 缓冲字符串一次读写一个字符串

十五、字符流的练习之把集合中的学生对象数据存储到文本文件

 需求:
     把ArrayList集合中的学生数据存储到文本文件
           每一个学生数据作为文件中的一行数据
 定义一个学生类。
  学生:
             学号,姓名,年龄,所在城市
              it001,张曼玉,35,北京
              it002,王祖贤,33,上海
              it003,林青霞,30,西安
 分析:
          A: 创建集合对象
          B:创建学生对象
          C:把学生对象添加到集合中
          D:创建字符缓冲输出流对象
          E:遍历集合,得到每一个学生对象,然后把该对象的数据拼接成一个指定格式的字符串写到文本文件
          F:释放资源
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

import bean.Student;

public class Demo01_ListToFile {
	public static void main(String[] args) throws IOException {
		BufferedWriter bw = new BufferedWriter(new FileWriter("Student.txt"));
		ArrayList<Student> list = new ArrayList<>();
		
		list.add(new Student("张三","a001", 21, "北京"));
		list.add(new Student("李四","a002", 22, "上海"));
		list.add(new Student("王五","a003", 23, "广州"));
		list.add(new Student("赵六","a004", 24, "深圳"));
		
		for (Student stu : list) {
			StringBuilder sb = new StringBuilder();
			sb.append(stu.getName()).append(",").append(stu.getId()).append(",").
					append(stu.getAge()).append(",").append(stu.getAddress());
			bw.write(sb.toString());
			bw.newLine();
		}
		
		bw.close();
	}
}

十六、字符流的练习之把文本文件中的学生对象数据读取到集合

 需求:
         从文本文件中读取学生数据到ArrayList集合中,并遍历集合
         每一行数据作为一个学生元素
        it001, 张曼玉,35,北京
         这里我们要使用String类中的一个方法:split()
 分析:
          A:创建字符缓冲输入流对象
          B:创建集合对象
          C:读取数据,每一次读取一行数据,把该行数据想办法封装成学生对象,并把学生对象存储到集合中
          D:释放资源

          E:遍历集合

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

import bean.Student;

public class Demo02_FileToList {
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new FileReader("Student.txt"));
		
		ArrayList<Student> list = new ArrayList<>();
		
		String line;
		
		while((line = br.readLine()) != null){
			String[] sArr = line.split(",");
			list.add(new Student(sArr[0],sArr[1],Integer.parseInt(sArr[2]),sArr[3]));
		}
		
		for (Student student : list) {
			System.out.println(student);
		}
		br.close();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值