Java总结09 IO体系之 字符流输出流(写入)与输入流(读取)和编码的概念与应用

一.字符流

在这里插入图片描述

1.字符流的本质与意义

本质:字符流 = 字节流 + 编码
意义:字符流是为了适应除英文字母以外的国家所诞生的概念.
比如为了储存一个文本文件,那么可以直接将中文(即字符流)转换为字节(即字节流).这直接省去了要把中文转换成Byte再去转换成字节的麻烦了.
注意:字符流只能输出输入文本文件,不能输入输出多媒体文件.
    因为多媒体文件的内容是不存在码表的,如果用字符流读写多媒体文件的话,字符流会将其内容强制对应到码表上,这样就会导致多媒体的文件数据出错.
普通字节流的文本逻辑: 文本/多媒体数据 <-----> Byte <-----> 字节集
字符流的文本逻辑: 文本 <-----> (隐性:字符变成编码) <------> 字节集;

2.输出字符流

默认编码格式:

OutputStreamWriter 自定义对象名 = new OutputStreamWriter(new FileOutputStream(路径/Flie对象));

列如:
OutputStreamWriter outputStreamWriterObj = new OutputStreamWriter(new FileOutputStream("\outputStreamWriterObj.txt"));
指定编码格式:

OutputStreamWriter 自定义对象名 = new OutputStreamWriter(new FileOutputStream(路径/File对象),用来表示编码的字符串);

列如:
OutputStreamWriter outputStreamWriterObjTwo = new OutputStreamWriter(new FileOutputStream("\outputStreamWriterObj.txt",true),“GB18030”);

3.输入字符流

默认编码格式:

InputStreamReader 自定义对象名 = new InputStreamReader(new FileInputStream(路径/File对象));

列如:
InputStreamReader inputStreamReaderObj = new InputStreamReader(new FileInputStream(“C:\Users\1\Documents\Tencent Files\aaa.txt”));

指定编码格式:

InputStreamReader 自定义对象名 = new InputStreamReader(new FileInputStream(路径/File对象),用来表示编码的字符串);

列如:
InputStreamReader inputStreamReaderObjAA = new InputStreamReader(new FileInputStream(“C:\Users\1\Documents\Tencent Files\aaa.txt”),“GBK”);

注意:输入字符流在处理文本时,需要考虑到原先文本的编码.不管是默认编码格式还是指定编码格式,都必须同被读文本的文件编码
InputStreamReader 把读过来的字节转换为字符
OutputStreamWriter 把字符转为字节去写入
在这里插入图片描述

4.方法的应用

在这里插入图片描述
在这里插入图片描述
输出流的方法:
方法1/

字符输出流对象名.close() 

意义:释放资源,在释放资源的同时会自动触发刷新机制

方法2/

字符输出流对象名.flush() 

意义:刷新
方法3/
字符输出流对象名. getEncoding()
返回此流使用的字符编码的名称。

方法4/

字符输出流对象名.write(char型数组,起始位置索引值,截取长度) 

列如:

//写入指定范围的字符数组.
		char[] charParam = {96, 97, 98, 99, 'Q', 'W', 'E'};
        outputStreamWriterObj.write(charParam, 3, 3);// 99 Q W
        outputStreamWriterObj.flush();//刷新

意义:截取字符数组的一部分数据来写入。

方法5/

字符输出流对象名.write(char型数组);

列如:

//字符(char)数组方式写入
        char[] charParam = {96, 97, 98, 99, 'Q', 'W', 'E'};
        outputStreamWriterObj.write(charParam);
        outputStreamWriterObj.flush();//刷新

意义:将整个数组数据写入

方法6/
字符输出流对象名.write(int c)
写入一个一个字符

方法7/

字符输出流对象名.write(String字符串, 起始位置索引值, 截取长度) 

列如:

outputStreamWriterObj.write("中国第一", 1, 2);//国第
outputStreamWriterObj.flush();//刷新

意义:将字符串的一部分当作数据写入

方法8/

字符输出流对象名.write(String字符串) 

列如:

//直接写入字符串
        outputStreamWriterObj.write("中国第一");
        outputStreamWriterObj.flush();//刷新

意义:将整个字符串当作数据写入

输入流的方法:
方法1/
字符输入流对象名.close()
意义:关闭流并释放与之相关联的任何系统资源。

方法2/
字符输入流对象名.getEncoding()
返回此流使用的字符编码的名称。

方法3/
字符输入流对象名.read()
读一个字符

方法4/
字符输入流对象名.read(char型数组, 起始位置索引值, 截取长度)
将字符读入数组的一部分。

方法5/

字符输入流对象名.read(char型数组)

列如:

     	char[] charParamTwo = new char[1024];
        int len;
        while((len = inputStreamReaderSuper.read(charParamTwo))!=-1){ // 此处len表示的时,长度为1024的数组'chaparamTwo'中有多少个数组填满了元素,如为500个,则read方法返回500个.
            outputStreamWriterSuper.write(charParamTwo, 0, len);  //len 和 length的区别,如果直接使用获取长度的length,则内容无区别,但是文件大小会大一点.
                                                                        //如果为len,同样内容无区别,但文件大小会小一点.
        }

意义:读入整个字节数组的数据.

二.字符的编码与解码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.概念

UTF-8编码中,一个汉字需要三个负数字节组成
GBK编码中,一个汉字需要二个负数字节组成
在字符中流,可以指定数据编码.
不指定的话,则根据系统版本而选择编码.
解码时必须根据其对应的编码进行解码,类似易语言中 编码用UTF-8 那么解码就必须用UTF-8

2.编码格式

1/用系统默认编码:
字符/字符串.getBytes(); //用系统默认编码进行编码
列如:
byte[] bytes = “世界”.getBytes();

2/用指定编码:
字符/字符串.getBytes(编码); //用指定编码去编码
列如:
byte[] bytesTwo = “世界”.getBytes(“GBK”);

3.解码格式

1/用系统默认编码:
new String(需要被编码的String类型内容);
列如:
String bytesBack = new String(bytes);

2/用指定编码:
new String(需要被编码的String类型内容,编码);
列如:
String bytesTwoBack = new String(bytesTwo,“GBK”);

三.字符流升级版(第二推荐)

FileWriterFileReader 分别是 OutputStreamWriterInputStreamReader升级版

意义

原因在于原先的字符IO创建语句过于麻烦,所以升级版的目的在于简化代码.功能无区别.

1.定义升级版字符输出流

格式:

FileWriter 自定义对象名 = new FileWriter(路径/File对象);

列如:
FileWriter fileWriterObj = new FileWriter("\outputStreamWriterSuper.txt");

2.定义升级版字符输入流

格式:

FileReader 自定义对象名 = new FileReader(路径/File对象);

列如:
FileReader fileReaderObj = new FileReader("\outputStreamWriterObj.txt");

四.字符流之缓冲流(最推荐)

字符缓冲流的意义

如同字节流的缓冲流一样,字符流的缓冲流同样可以提高数据的读写效率.

1.字符缓冲流的创建格式

1/字符输出缓冲流
格式:

  BufferedWriter 自定义对象名 = new BufferedWriter(new FileWriter(路径/File对象));
列如:
BufferedWriter bufferedWriterObj = new BufferedWriter(new FileWriter("\\bufferedWriterObj.txt"));

2/字符输入缓冲流
格式:

BufferedReader 自定义对象名 = new BufferedReader(new FileReader(路径/File对象));

列如:
BufferedReader bufferedReaderObj = new BufferedReader(new FileReader(“C:\Users\1\Documents\Tencent Files\aaa.txt”))

2.特有方法的应用

多数方法同同字符流升级版和基本版一样,而重点掌握的特有方法有3个:
1/
格式:自定义输入流对象名.readLine​()
列如:bufferedReaderObj.readLine()
意义:一次只读取一行字符串

2/
格式:自定义输出流对象名.ritervoid newLine​()
列如:bufferedWriterObj.newLine();
意义:自动根据内容被读文件内容来写入换行符.
用于文本中的换行符.它的作用是先判断获取到的该行字符串有没有换行符,
如果有,不论你是什么系统(系统不同,换行符也不同),都能将文本中的的隐性换行符给替代掉,用newLine表示换行.
如果不用,写出的文件很可能缺失了原有的换行符.

3/
格式:自定义输出流对象名. write(字符串/char数组);
列如:bufferedWriterObj.write(temp);
意义:一次写一个字符串

基本字符流输出输入演示类:Characeter.java

public class Characeter {
    public static void main(String[] args) throws Exception {

// 一/字符串的编码与解码
        //默认编码和默认解码
        byte[] bytes = "世界".getBytes();//编码 --- 系统默认编码进行编码.
        System.out.println("默认编码:" + Arrays.toString(bytes));
        String bytesBack = new String(bytes);//解码 --- 系统默认编码进行解码.
        System.out.println("默认解码" + bytesBack);

        System.out.println("===========");

        //指定编码和指定解码
        byte[] bytesTwo = "世界".getBytes("GBK");//编码 --- 用指定编码GBK进行编码,如若要对其进行解码,其解码的编码也要一致,比如也要是GBK.
        System.out.println("指定编码GBK:" + Arrays.toString(bytesTwo));
        String bytesTwoBack = new String(bytesTwo, "GBK");//解码 --- 用指定编码进行解码,被解码之内容所用的编码,要同此一致,如两者都是GBK编码.
        System.out.println("指定解码GBK:" + bytesTwoBack);

        System.out.println("===========");

// 二/字符流


        //创建输出字节流
        OutputStreamWriter outputStreamWriterObj = new OutputStreamWriter(new FileOutputStream("\\outputStreamWriterObj.txt", true));
        OutputStreamWriter outputStreamWriterObjTwo = new OutputStreamWriter(new FileOutputStream("\\outputStreamWriterObj.txt", true), "GB18030");


        //字符流(OutputStreamWriter)写数据的五种方式

        //第一种,以int型写,系统会自动转换成一个一个的char型.
        outputStreamWriterObj.write(121212);
        outputStreamWriterObj.flush();//在写入字节流后,需要用flush方法进行刷新.如果不刷新的话,用给write方法传递的数据就无法成功写入到文件中.

        //第二种,字符(char)数组方式写入
        char[] charParam = {96, 97, 98, 99, 'Q', 'W', 'E'};
        outputStreamWriterObj.write(charParam);
        outputStreamWriterObj.flush();//刷新

        //第三种,写入指定范围的字符数组.
        outputStreamWriterObj.write(charParam, 3, 3);// 99 Q W
        outputStreamWriterObj.flush();//刷新

        //第四种,直接写入字符串
        outputStreamWriterObj.write("中国第一");
        outputStreamWriterObj.flush();//刷新

        //第四种,写入字符串的一部分
        outputStreamWriterObj.write("中国第一", 1, 2);//国第
        outputStreamWriterObj.flush();//刷新


        //使用close命令关闭资源的时候,colse会自动的先调用flush方法u触发刷新,以便让新的字节流能成功被写入.
        outputStreamWriterObj.close();



        //创建输入字节流
        //InputStreamReader
        InputStreamReader inputStreamReaderObj = new InputStreamReader(new FileInputStream("C:\\Users\\1\\Documents\\Tencent Files\\aaa.txt"));
        InputStreamReader inputStreamReaderObjAA = new InputStreamReader(new FileInputStream("C:\\Users\\1\\Documents\\Tencent Files\\aaa.txt"), "GBK");//以编码形式
        inputStreamReaderObj.close();
/*
void close​() 关闭流并释放与之相关联的任何系统资源。
String getEncoding​() 返回此流使用的字符编码的名称。
int read​() 读一个字符
int read​(char[] cbuf, int offset, int length) 将字符读入数组的一部分。 如果为读取全部,那么索引值为0.
boolean ready​() 告诉这个流是否准备好被读取。

 */
        //实现:复制一个文本内容到另一个文件中
        InputStreamReader inputStreamReaderSuper = new InputStreamReader(new FileInputStream("C:\\Users\\1\\Documents\\Tencent Files\\aaa.txt"));
        OutputStreamWriter outputStreamWriterSuper = new OutputStreamWriter(new FileOutputStream("\\outputStreamWriterSuper.txt"));

        //一次读取一组数组(数组长度中带有元素的数组)的字符数据,
        char[] charParamTwo = new char[1024];
        int len;
        while((len = inputStreamReaderSuper.read(charParamTwo))!=-1){ // 此处len表示的时,长度为1024的数组'chaparamTwo'中有多少个数组填满了元素,如为500个,则read方法返回500个.
            outputStreamWriterSuper.write(charParamTwo, 0, len);  //len 和 length的区别,如果直接使用获取长度的length,则内容无区别,但是文件大小会大一点.
                                                                        //如果为len,同样内容无区别,但文件大小会小一点.
        }

  outputStreamWriterSuper.close();
        inputStreamReaderSuper.close();


    }
}

五.字符流/升级版字符流/缓冲字符流的包囊关系

字符流/升级版字符流/缓冲字符流的包囊关系在这里插入图片描述

字符缓冲流演示类BufferedReaderAndBufferedWrider.java

public class BufferedReaderAndBufferedWrider {

    public static void main(String[] args) throws IOException {
        BufferedWriter bufferedWriterObj = new BufferedWriter(new FileWriter("\\bufferedWriterObj.txt"));//缓冲输出流

        BufferedReader bufferedReaderObj = new BufferedReader(new FileReader("C:\\Users\\1\\Documents\\Tencent Files\\aaa.txt"));//缓冲输入流

        //完成复制文件,其中要用到特有方法
        //特有方法:
        // bufferedReader String readLine​() 一次只读取一行字符串。
        //bufferedWriter ritervoid newLine​() 写一行分隔符。
        //bufferedWriter riter write() 一次写一个字符串

        String temp;
        while ((temp = bufferedReaderObj.readLine()) != null) {

            bufferedWriterObj.write(temp);
            bufferedWriterObj.newLine(); //用于文本中的换行符.它的作用是先判断获取到的该行字符串有没有换行符,
            // 如果有,不论你是什么系统(系统不同,换行符也不同),都能将文本中的的隐性换行符给替代掉,用newLine表示换行.
            //如果不用,写出的文件很可能缺失了原有的换行符.


            bufferedWriterObj.flush();
        }
        bufferedWriterObj.close();
        bufferedReaderObj.close();


 
}

缓冲流案例-将集合写到硬盘文本

要求:将集合中的数据写到硬盘文件中

public class BufferedReaderAndBufferedWrider {

    public static void main(String[] args){
	 mapListOfIo();
	 
	}
 public static void mapListOfIo() throws IOException {

        Map<Integer, String> mapObj = new HashMap<>();

        mapObj.put(1, "中国");
        mapObj.put(2, "崛起");
        mapObj.put(3, "国运");
        mapObj.put(4, "昌隆");

        Set<Integer> setMapObj = mapObj.keySet();//列出所有键

        BufferedWriter bufferedWriterObj = new BufferedWriter(new FileWriter("\\bufferedWriterObjOfMapList.txt"));//缓冲输出流


        for (Integer integer : setMapObj) {
            String a = mapObj.get(integer);//根据键找到值
            bufferedWriterObj.write(a);//写入
            bufferedWriterObj.newLine();//换行
            bufferedWriterObj.flush();//刷新


        }

        bufferedWriterObj.close();//释放资源
    }
  }  

缓冲流案例-将硬盘文本写到集合

要求:将硬盘中的’中日文档案’文件写入到集合中,然后随机打印其中一个句子

public class BufferedReaderAndBufferedWrider {

    public static void main(String[] args){
	 IoOfMapList();
	 
	}
	 public static void IoOfMapList() throws IOException {

        BufferedReader bufferedReaderObj = new BufferedReader(new FileReader("\\MapListOfbufferedWriterObj.txt"));//缓冲输入流

        ArrayList<String> arrayListObj = new ArrayList<>();
        String a;
        while ((a = bufferedReaderObj.readLine()) != null) {//如果缓冲输入流通过readLine获取到的某一行有内容,则进行循环.readLine获取到的内容会以String类型返回,
                                                            // 因此判断左侧的String变量'a'是否为空即可.

            arrayListObj.add(a);
            System.out.println("加入的元素为:" + a);
        }

        Random r = new Random();
        int number = r.nextInt(arrayListObj.size());

        System.out.println("随机元素为:" + arrayListObj.get(number));


    }
}

缓冲流案例-学生信息到硬盘文本

要求:创建一个学生对象,将学生信息输出到一个硬盘文件中.格式:学号,姓名,年龄,地址

public class BufferedReaderAndBufferedWrider {

    public static void main(String[] args){
	 studentInfoOfFile();
}
 public static void studentInfoOfFile() throws IOException {

        Student studentObj = new BufferedReaderAndBufferedWrider().new Student("10001","刘亦菲",26,"深圳");
        Student studentObjTwo = new BufferedReaderAndBufferedWrider().new Student("10002","赵丽颖",21,"北京");
        Student studentObjThree = new BufferedReaderAndBufferedWrider().new Student("10003","迪丽热巴",28,"上海");
        Student studentObjFour = new BufferedReaderAndBufferedWrider().new Student("10001","刘若英",37,"广州");
        BufferedWriter bufferedWriterObj = new BufferedWriter(new FileWriter("\\StudentInfo.txt"));

        ArrayList<Student> arrayListObj = new ArrayList<>();
        arrayListObj.add(studentObj);
        arrayListObj.add(studentObjTwo);
        arrayListObj.add(studentObjThree);
        arrayListObj.add(studentObjFour);
        for (Student student : arrayListObj) {

            String studentInfo = "学号:"+student.getStudentNum()+" 姓名:"+student.getName()+" 年龄:"+student.getAge()+" 地址:"+student.getAddress();
            bufferedWriterObj.write(studentInfo);
            bufferedWriterObj.newLine();//换行符
            bufferedWriterObj.flush();


        }
                bufferedWriterObj.close();




    }
 class Student{

        private String studentNum;
        private String name;
        private int age;
        private String address;

        public String getStudentNum() {
            return studentNum;
        }

        public void setStudentNum(String studentNum) {
            this.studentNum = studentNum;
        }

        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 getAddress() {
            return address;
        }

        public void setAddress(String address) {
            this.address = address;
        }

        public Student() {
        }

        public Student(String studentNum, String name, int age, String address) {
            this.studentNum = studentNum;
            this.name = name;
            this.age = age;
            this.address = address;
        }
    }
}
	 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值