javaIo之字符流

举报
兰舟千帆 发表于 2022/07/21 18:48:13 2022/07/21
【摘要】 字符流说明 字符输入流读数据的方法Reader是一个抽象类public abstract class Readerextends Objectimplements Readable, Closeable用于读取字符流的抽象类。子类必须实现的方法只有 read(char[], int, int) 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。我们...

字符流说明

字符输入流读数据的方法

Reader是一个抽象类

public abstract class Readerextends Objectimplements Readable, Closeable

用于读取字符流的抽象类。子类必须实现的方法只有 read(char[], int, int) 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。

我们主要演示的实现类就是InputStreamReader

public class InputStreamReaderextends Reader

InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。
每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。
为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。例如:
BufferedReader in
= new BufferedReader(new InputStreamReader(System.in));

当然这个缓冲流我们在后面举例

InputStreamReader的主要构造方法有这么几个

构造方法摘要
1:InputStreamReader(InputStream in)
创建一个使用默认字符集的 InputStreamReader。
2:InputStreamReader(InputStream in, Charset cs)
创建使用给定字符集的 InputStreamReader。
3:InputStreamReader(InputStream in, CharsetDecoder dec)
4: 创建使用给定字符集解码器的 InputStreamReader。
InputStreamReader(InputStream in, String charsetName)
创建使用指定字符集的 InputStreamReader。

主要的方法

void close()
关闭该流并释放与之关联的所有资源。
String getEncoding()
返回此流使用的字符编码的名称。
int read()
读取单个字符。
int read(char[] cbuf, int offset, int length)
将字符读入数组中的某一部分。
boolean ready()
判断此流是否已经准备好用于读取。

从提供的构造方法的·参数我们可以了解到这个实现类基本的底层还是有字节流的实现。或者可以跟进源码。

在这里插入图片描述
==我们可以认为这个字符输入流实现类基本实现的就是字节流加上编码的效果。==

现在我们可以去看看它的读取数据的方法。(到源码中)
在这里插入图片描述
在这里插入图片描述
我们可以这样用字符流进行简单读取

package io_demo;

import java.io.*;

public class IODemo_10 {
    public static void main(String args[]) throws IOException {

        InputStreamReader isr = new InputStreamReader(new FileInputStream("E:\\java_doc\\src\\io_demo\\demo_pratice"));
        

      
        int ch ;
        while((ch=isr.read())!=-1)
        {
            System.out.println((char)ch);
        }
        isr.close();

    }
}

当然还是可以进行一次读取一个字符数组的方法

package io_demo;



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

public class IoDemo_12 {
    public static void main(String args[]) throws IOException {
        //字符流读数据
        InputStreamReader isr = new InputStreamReader(new FileInputStream("E:\\java_doc\\src\\io_demo\\demo_pratice"));
//        int ch;
//        while((ch=isr.read())!=-1)
//        {
//            System.out.println((char)ch);

        char[] chs = new char[1024];
        int len;
        while ((len = isr.read(chs)) != -1) {
            System.out.println(new String(chs,0,len));

        }
        isr.close();
    }
}

字符缓冲输入流

我们照样可以使用缓冲流
在这里插入图片描述
这个缓冲流也继承了Reader类,基本上也提供了父类有的read()等方法,另外还有readline()方法。我们在后面的例子中使用。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package io_demo;



import java.io.*;

public class DemoPratice01 {
    public static void main(String args[]) throws IOException {
        InputStreamReader isr = new InputStreamReader(new FileInputStream("E:\\java_doc\\src\\io_demo\\demo_01"));
        BufferedReader br= new BufferedReader(isr);
        int ch;
        while((ch=br.read())!=-1)
        {
            System.out.print((char)ch);
        }
        char[] chars = new char[1024];
        int len;
        while ((len = br.read(chars))!=-1)
        {
            System.out.println(new String(chars,0,len));
        }

    }
}

使用字符缓输入流可以实现一行一行读取的操作。

BufferedReader br = new BufferedReader(new FileReader("bw.newLine();"));
         String line;
         while((line = br.readLine())!=null)
         {
             System.out.println(line);
         }

字符输出流写数据的方法

public abstract class Writerextends Objectimplements Appendable, Closeable, Flushable

写入字符流的抽象类。子类必须实现的方法仅有 write(char[], int, int)、flush() 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。

还是首先选一个实现类开始一些说明

public class OutputStreamWriterextends Writer

OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。
每次调用 write() 方法都会导致在给定字符(或字符集)上调用编码转换器。在写入底层输出流之前,得到的这些字节将在缓冲区中累积。可以指定此缓冲区的大小,不过,默认的缓冲区对多数用途来说已足够大。注意,传递给 write() 方法的字符没有缓冲。
为了获得最高效率,可考虑将 OutputStreamWriter 包装到 BufferedWriter 中,以避免频繁调用转换器。例如:
Writer out
= new BufferedWriter(new OutputStreamWriter(System.out));

主要的构造方法

1:OutputStreamWriter(OutputStream out)
创建使用默认字符编码的 OutputStreamWriter。
2:OutputStreamWriter(OutputStream out, Charset cs)
创建使用给定字符集的 OutputStreamWriter。
3:OutputStreamWriter(OutputStream out, CharsetEncoder enc)
创建使用给定字符集编码器的 OutputStreamWriter。
OutputStreamWriter(OutputStream out, String charsetName)
创建使用指定字符集的 OutputStreamWriter。

常用的方法

void close()
关闭此流,但要先刷新它。
void flush()
刷新该流的缓冲。
String getEncoding()
返回此流使用的字符编码的名称。
void write(char[] cbuf, int off, int len)
写入字符数组的某一部分。
void write(int c)
写入单个字符。
void write(String str, int off, int len)
写入字符串的某一部分。

很明显这样的设计和输入流还是十分对称的。
下面还是简单的去使用它。

package io_demo;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class IoDemo__ {
    public static void main(String args[]) throws IOException {
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("E:\\java_doc\\src\\io_demo\\demo_pratice1"));
        osw.write("hello");
        char[] chars = new char[]{'a','b','c'};
        osw.write(chars,0,chars.length);

    }
}

字符缓冲输出流

同样可以使用缓冲流

public class BufferedWriter extends Writer {

    private Writer out;

    private char cb[];
    private int nChars, nextChar;

    private static int defaultCharBufferSize = 8192;

缓冲流使用到的一些方法

主要的构造方法
在这里插入图片描述
在这里插入图片描述
一些普通方法

BufferedWriter bw = new BufferedWriter(osw);

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
同样还有进行读入行的方法
在这里插入图片描述
使用的时候这样将字符输出流对象进行传入就可以

BufferedWriter bw = new BufferedWriter(osw);

用输入输出实现数据的复制

package io_demo;

import java.io.*;

public class IoDemo13 {
    //字符流进行复制文件
    public static void main(String args[]) throws IOException {
        InputStreamReader isr = new InputStreamReader(new FileInputStream("E:\\java_doc\\src\\io_demo\\IoDemo_12.java"));
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("E:\\java_doc\\src\\io_demo\\Demo_Copy.java"));
        int ch;
//        while((ch = isr.read())!=-1)
//        {
//            osw.write(ch);
//        }
        //一次读取一个字符数组
//        char[] chars = new char[1024];
//        int len;
//        while((len= isr.read(chars))!=-1)
//        {
//            osw.write(chars,0,len);
//        }
        osw.close();
        isr.close();
    }
}

但是其实我们还可以使用这个两个类下的子类,更方便的进行操作。

package io_demo;

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

public class IoDemo_14 {
    public static void main(String args[]) throws IOException {
        //使用下面的子类(可以简化书写长度)
        FileReader fr = new FileReader("E:\\java_doc\\src\\io_demo\\demo_pratice");
        FileWriter fw = new FileWriter("E:\\java_doc\\src\\io_demo\\demo_01");
        int ch;
        while((ch = fr.read())!=-1)
        {
            fw.write(ch);
        }
        char[] chars = new char[1024];
        int len;
        while((len= fr.read(chars))!=-1)
        {
            fw.write(chars,0,len);
        }
        fw.close();
        fr.close();
    }

}

同样该子类也可以结合字符缓冲流

package io_demo;



import java.io.*;

public class IoDemo15 {
    public static void main(String args[]) throws IOException {
        //字符缓冲流
        FileWriter fw = new FileWriter("E:\\java_doc\\src\\io_demo\\demo_pratice");
        BufferedWriter bw = new BufferedWriter(fw);
        bw.write("Hello");
        bw.close();
        BufferedReader br = new BufferedReader(new FileReader("E:\\java_doc\\src\\io_demo\\demo_01"));
        // 一次读一个字符数据
        int ch;
        while((ch=br.read())!=-1)
        {

            System.out.println((char)ch);

        }
        //一次读取一个字符数组
        char[] chars = new char[1024];
        int len;
        while((len=br.read(chars))!=-1)
        {
          System.out.println(new String(chars,0,len));
        }
    }
}

做一个随机点名器

在这里插入图片描述
假设文件中有这些名字,然后我们从中读取信息,并随机输出。这样就时一个随机点名器了。

package io_demo;

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

//从文件中读取数据,做一个随机点名器
public class IoDemo18 {
    public static void main(String args[]) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("E:\\java_doc\\src\\io_demo\\demo_pratice"));
        //创建ArrayList对象
        ArrayList<String> array = new ArrayList<String>();
        String line;
        while((line= br.readLine())!=null)
        {
            array.add(line);
        }
        br.close();
        Random r = new Random();
        int i = r.nextInt(array.size());
        String name = array.get(i);
        System.out.println("幸运者是"+name);

    }
}

在这里插入图片描述

集合到文件(将对象信息拼接输入到文件)

首先我们创建一个学术类

package io_demo;

public class Student {
    private String sid;
    private String name;
    private int age;
    private String address;
    public Student()
    {

    }

    public Student(String sid, String name, int age, String address) {
        this.sid = sid;
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public String getSid() {
        return sid;
    }

    public void setSid(String sid) {
        this.sid = sid;
    }

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

测试代码

package io_demo;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

public class IoDemo19 {
    //集合到文件,改进版
    public static void main(String args[]) throws IOException {
        //创建ArrayList集合
        ArrayList<Student> array = new ArrayList<>();
        Student s1 = new Student("001", "jgdabc", 19, "山西");
        Student s2 = new Student("002", "兰舟千帆", 20, "山西");
        Student s3 = new Student("003", "潇潇", 18, "湖北");
        Student s4 = new Student("004", "小雨", 21, "河北");
        Student s5 = new Student("005", "叶灵芸", 22, "浙江");
        array.add(s1);
        array.add(s2);
        array.add(s3);
        array.add(s4);
        array.add(s5);
        //创建字符流输出对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\\\java_doc\\\\src\\\\io_demo\\\\Student.txt"));
        for (Student s : array) {
            StringBuilder sb = new StringBuilder();
            sb.append(s.getSid()).append(",").append(s.getName())
                    .append(",").append(s.getAge()).append(",").append(s.getAddress());
            bw.write(sb.toString());
            bw.newLine();
            bw.flush();
        }
        //释放资源
        bw.close();

    }
}

在这里插入图片描述

文件到集合(将文件中的人物属性通过对象存放于集合中,然后进行遍历)

还是基本的学术类

package io_demo;

public class Student {
    private String sid;
    private String name;
    private int age;
    private String address;
    public Student()
    {

    }

    public Student(String sid, String name, int age, String address) {
        this.sid = sid;
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public String getSid() {
        return sid;
    }

    public void setSid(String sid) {
        this.sid = sid;
    }

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

测试类

package io_demo;

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

//将文本文件当中的数据督导集合当中
public class IoDemo_20 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("E:\\java_doc\\src\\io_demo\\Student.txt"));
        ArrayList<Student> array = new ArrayList<>();
        //调用字符缓冲输入流对象的方法读取数据
        String line;
        while ((line = br.readLine()) != null) {
            String[] strArray = line.split(",");
            Student s = new Student();
            //将字符串数组的每一个元素取出来对应的复制给学生对象的成员变量值
            s.setSid(strArray[0]);
            s.setName(strArray[1]);
            s.setAge(Integer.parseInt(strArray[2]));
            s.setAddress(strArray[3]);
            array.add(s);
        }
        br.close();
        for (Student s : array) {
            System.out.println(s.getSid() + "," + s.getName() + "," + s.getAge() + "," + s.getAddress());
        }
        


    }

}

在这里插入图片描述

将学生成绩排序,并将数据写入文件中(排序采用多级条件)

我们可以先创建一个学生类

package io_demo;

public class Student01 {
    private String name;
    private int chinese;
    private int math;
    private int english;

    public Student01() {
        super();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getChinese() {
        return chinese;
    }

    public void setChinese(int chinese) {
        this.chinese = chinese;
    }

    public int getMath() {
        return math;
    }

    public void setMath(int math) {
        this.math = math;
    }

    public int getEnglish() {
        return english;
    }

    public void setEnglish(int english) {
        this.english = english;
    }

    public Student01(String name, int chinese, int math, int english) {
        this.name = name;
        this.chinese = chinese;
        this.math = math;
        this.english = english;
    }

    public int getSum() {
        return this.chinese + this.english + this.math;
    }
}

创建学生类的唯一作用就是来获取对象,存放相关的属性。

然后我们再创建一个测主类

package io_demo;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;

public class Student01_Demo {
    public static void main(String[] args) throws IOException {
        TreeSet<Student01> ts = new TreeSet<>(new Comparator<Student01>() {
            @Override
            public int compare(Student01 s1, Student01 s2) {
                int num = s2.getSum() - s1.getSum();
                int num2 = num == 0 ? s1.getChinese() - s2.getChinese() : num;
                int num3 = num2 == 0 ? s1.getMath() - s2.getMath() : num2;
                int num4 = num3 == 0 ? s1.getName().compareTo(s2.getName()) : num3;
                return num4;
                //return 0;
            }
        });
        for (int i = 0; i < 5; i++) {
            Scanner sc = new Scanner(System.in);
            System.out.println("请录入第" + (i + 1) + "个学生信息");
            System.out.println("姓名:");
            String name = sc.nextLine();
            System.out.println("语文成绩:");
            int chinese = sc.nextInt();
            System.out.println("数学成绩:");
            int math = sc.nextInt();
            System.out.println("英语成绩:");
            int english = sc.nextInt();
            Student01 s = new Student01();
            s.setName(name);
            s.setChinese(chinese);
            s.setMath(math);
            s.setEnglish(english);
            ts.add(s);
        }
        BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\java_doc\\src\\io_demo\\Student01.txt"));
        for (Student01 s : ts) {
            StringBuilder sb = new StringBuilder();
            sb.append(s.getName()).append(",").append(s.getChinese())
                    .append(",").append(s.getMath()).append(",").append(s.getEnglish()).append(",").append(s.getSum());

            bw.write(sb.toString());
            bw.newLine();
            bw.flush();
        }
        bw.close();
    }
}

在这里插入图片描述

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。