JAVASE(17)I/O流

Keyword:

  • IO流
  • 字节流子类
    • FileOutputStream
    • FileInputStream
    • BufferedOutputStream
    • BufferedInputStream
    • FileOutputStream和FileInputStream复制文件
  • 字符流子类
    • 字符流出现的原因及编码表概述和常见编码表
    • String类中的编码和解码问题
    • OutputStreamWriter
    • InputStreamReader
    • FileWriter和FileReader复制文本文件
    • 字符串高效流
    • 综合

IO流

在这里插入图片描述

1.IO流的概念

IO流用来处理设备之间的数据传输

2.IO流分类

  • 按照数据流向 (站在内存角度)
    • 输入流----读入数据
    • 输出流----写出数据

在这里插入图片描述

  • 按照数据类型
    • 字节流 可以读写任何类型的文件 比如音频 视频 文本文件
    • 字符流 只能读写文本文件

3.IO流的分类

在这里插入图片描述


字节流

FileOutputStream类

1.FileOutputStream写出数据

构造方法:

FileOutputStream(File file)
FileOutputStream(String name)

案例演示:

public class Demo {
    public static void main(String[] args) {
        FileOutputStream out=null;
        try {
             out = new FileOutputStream(".txt");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
  • 创建字节输出流对象了做了几件事情?

    1. 调用系统资源创建a.txt文件
    2. 创建了一个out对象
    3. 把out对象指向这个文件
  • 为什么一定要close()?

    1. 通知系统释放关于管理a.txt文件的资源

    2. 让Io流对象变成垃圾,等待垃圾回收器对其回收

2.FileOutputStream的三个write()方法

public void write(int b):写一个字节  超过一个字节 砍掉前面的字节
public void write(byte[] b):写一个字节数组
public void write(byte[] b,int off,int len):写一个字节数组的一部分

案例演示:

public class Demo {
    public static void main(String[] args) {
        FileOutputStream out=null;
        try {
             out = new FileOutputStream(".txt");
             out.write(97);
             out.write(new byte[]{'1','9','2','9','2','9','2'});
             out.write(new byte[]{'1','9','2','9','2','9','2'},1,3);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

3.FileOutputStream写出数据实现换行和追加写入

案例演示:

public class Demo {
    public static void main(String[] args) {
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(".txt", true);
            //根据构造函数的重载,true表示追加
            out.write(97);
            out.write("\r\n".getBytes());
            out.write(new byte[]{'1', '9', '2', '9', '2', '9', '2'});
            out.write("\r\n".getBytes());
            out.write(new byte[]{'1', '9', '2', '9', '2', '9', '2'}, 1, 3);
            out.write("\r\n".getBytes());
            
            //windows下的换行符 \r\n
		  	//		Linux		\n
            //		Mac			\r
            
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

4.FileOutputStream写出数据加入异常处理

案例演示:

public class Demo {
    public static void main(String[] args) {
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(".txt");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

FileInputStream

1.FileInputStream读取数据一次一个字节

案例演示:

public class Demo {
    public static void main(String[] args) {
        FileInputStream in = null;
        try {
            in = new FileInputStream(".txt");
            while (in.read()!=-1){
                //一个一个的读取字节,当找不到输出-1
                System.out.println(in.read());
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

2.字节流复制文本文件

字节流一次读写一个字节复制文本文件

分析:

  • a: 创建字节输入流对象和字节输出流对象
  • b: 频繁的读写操作
  • c: 释放资源

案例演示:

public class Demo {
    public static void main(String[] args) {
        FileInputStream in = null;
        FileOutputStream out=null;
        try {
            in = new FileInputStream(".txt");
            out=new FileOutputStream("a.txt");
            int len=0;
            while ((len=in.read())!=-1){
              out.write(len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

3.FileInputStream读取数据一次一个字节数组

案例演示: int read(byte[] b):一次读取一个字节数组

public class Demo {
    public static void main(String[] args) {
        FileInputStream in = null;
        try {
            in = new FileInputStream(".txt");
            int len = 0;
            //表示在字节数组中的个数
            byte[] bytes = new byte[1024 * 8];
            while ((len = in.read()) != -1) {
                System.out.println(in.read(bytes, 0, len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

4.字节流复制文本文件

案例演示:

public class Demo {
    public static void main(String[] args) {
        FileInputStream in = null;
        FileOutputStream out=null;
        try {
            in = new FileInputStream(".txt");
            out=new FileOutputStream("a.txt");
            int len=0;
            byte[] bytes = new byte[1024 * 8];
            while ((len=in.read())!=-1){
                out.write(bytes,0,len);
                out.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

5.FileOutputStream和FileInputStream复制文件(内嵌套文件夹)

案例演示:

public class Demo1 {
    public static void main(String[] args) throws IOException {
        File file = new File("C:\\Users\\Administrator\\Desktop\\note");
        File outfile = new File("C:\\Users\\Administrator\\Downloads\\note");
        Copyfile(file, outfile);
    }
    private static void Copyfile(File file, File outfile) {
        outfile.mkdirs();
        File[] listFiles = file.listFiles();
        for (File listFile : listFiles) {
            if (listFile.isFile()) {
                FileInputStream in = null;
                FileOutputStream out = null;
                try {
                    in = new FileInputStream(listFile.getAbsolutePath());
                    out = new FileOutputStream(outfile.getAbsolutePath() + "\\" + listFile.getName());
                    int len = 0;
                    byte[] bytes = new byte[1024 * 8];
                    while ((len = in.read(bytes)) != -1) {
                        out.write(bytes);
                        out.flush();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    try {
                        out.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            } else if (listFile.isDirectory()) {
                File file1 = new File(outfile.getAbsolutePath() + "\\" + listFile.getName());
                Copyfile(listFile, file1);
            }
        }
    }
}

BufferedOutputStream和BufferedInputStream

字节流四种方式复制MP3并测试效率

案例演示:
通过以下四个代码测试效率。
基本字节流一次读写一个字节 //143
基本字节流一次读写一个字节数组 //8
高效字节流一次读写一个字节 //8
高效字节流一次读写一个字节数组 //8

结论:由于引入了缓冲区的思想,所以读写的速度变快


字符流

字符流出现的原因及编码表概述和常见编码表

在这里插入图片描述

String类中的编码和解码问题

在这里插入图片描述

转换流OutputStreamWriter

1.构造方法

OutputStreamWriter(OutputStream out):根据默认编码(GBK)把字节流的数据转换为字符流
OutputStreamWriter(OutputStream out,String charsetName):根据指定编码把字节流数据转换为字符流

案例演示:

public class Demo1 {
    public static void main(String[] args) throws IOException {
        OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("a.txt"));
        writer.write(97);
        writer.flush();
        //字符流每次写完,都需要刷新一下
    }
}
a.txt文档中显示的是a

2.字符流的5种写数据的方式

方法概述

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

案例演示:

public class Demo1 {
    public static void main(String[] args) throws IOException {
        OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("a.txt"),"utf-8");
        writer.write(97);
        writer.write("\r\n");
        writer.flush();
        writer.write(new char[]{'你','好','世','界'});
        writer.write("\r\n");
        writer.flush();
        writer.write(new char[]{'你','好','世','界'},2,2);
        writer.write("\r\n");
        writer.flush();
        writer.write("你好世界");
        writer.write("\r\n");
        writer.flush();
        writer.write("你好java世界",2,4);
        writer.write("\r\n");
        //换行符
        writer.flush();
        //字符流每次写完,都需要刷新一下
        writer.close();
        //每次结束,都要关闭流,清理内存
    }
}

转换流InputStreamReader

1.构造方法

InputStreamReader(InputStream is):用默认的编码(GBK)读取数据
InputStreamReader(InputStream is,String charsetName):用指定的编码读取数据

案例演示:

public class Demo2 {
    public static void main(String[] args) throws IOException {
        InputStreamReader reader = new InputStreamReader(new FileInputStream("a.txt"));
        System.out.println(reader.read());
        System.out.println(reader.read());
        System.out.println(reader.read());
        System.out.println(reader.read());
        System.out.println(reader.read());
        reader.close();
    }
}
----------------------
97
13
10
20320
22909

2.字符流的2种读数据的方式

  • public int read() 一次读取一个字符
    

    案例演示:

    public class Demo2 {
        public static void main(String[] args) throws IOException {
            InputStreamReader reader = new InputStreamReader(new FileInputStream("a.txt"));
            while (reader.read()!=-1){
                System.out.println(reader.read());
            }
            reader.close();
        }
    }
    
  • public int read(char[] cbuf) 一次读取一个字符数组 如果没有读到 返回-1
    

    案例演示:

    public class Demo2 {
        public static void main(String[] args) throws IOException {
            InputStreamReader reader = new InputStreamReader(new FileInputStream("a.txt"));
            int len = 0;
            char[] chars = new char[1024 * 8];
            while ((len = reader.read(chars)) != -1) {
                reader.read(chars, 0, len);
            }
            reader.close();
        }
    }
    

3.字符流复制文本文件

案例演示:

public class Demo {
    public static void main(String[] args) throws IOException {
        OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("b.txt"));
        InputStreamReader reader = new InputStreamReader(new FileInputStream("a.txt"));
        int len=0;
        char[] chars = new char[100];
        while ((len=reader.read(chars))!=-1){
            writer.write(chars,0,len);
            writer.flush();
        }
        writer.close();
    }
}

FileWriter和FileReader

1.概念:

转换流的名字比较长,而我们常见的操作都是按照本地默认编码实现的,所以,为了简化书写,转换流提供了对应的子类。

转换流 便捷类

OutputStreamWriter ------- FileWriter

InputStreamReader ------- FileReader

案例演示:FileWriter和FileReader复制文本文件

public class Demo3 {
    public static void main(String[] args) throws IOException {
        FileWriter writer = new FileWriter("c.txt");
        FileReader reader = new FileReader("a.txt");
        int len = 0;
        char[] chars = new char[100];
        while ((len = reader.read(chars)) != -1) {
            writer.write(chars, 0, len);
            writer.flush();
        }
        writer.close();
        reader.close();
    }
}

字符缓冲流

1.字符缓冲流复制文本文件

public class Demo4 {
    public static void main(String[] args) throws IOException {
        BufferedWriter writer = new BufferedWriter(new FileWriter("d.txt"));
        BufferedReader reader = new BufferedReader(new FileReader("a.txt"));
        int len = 0;
        char[] chars = new char[1000];
        while ((len = reader.read(chars)) != -1) {
            writer.write(chars, 0, len);
            writer.flush();
        }
        writer.close();
        reader.close();
    }
}

2.字符缓冲流的特殊功能

BufferedWriter:public void newLine():根据系统来决定换行符 具有系统兼容性的换行符
BufferedReader:public String readLine():一次读取一行数据  是以换行符为标记的 读到换行符就换行 没读到数据返回null,包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null

案例演示:

public class Demo4 {
    public static void main(String[] args) throws IOException {
        BufferedWriter writer = new BufferedWriter(new FileWriter("d.txt"));
        BufferedReader reader = new BufferedReader(new FileReader("a.txt"));
        String line=reader.readLine();
        while (line!=null) {
            writer.write(line);
            writer.newLine();
            writer.flush();
        }
        writer.close();
        reader.close();
    }
}

3.字符缓冲流的特殊功能复制文本文件

案例演示:

public class Demo4 {
    public static void main(String[] args) throws IOException {
        BufferedWriter writer = new BufferedWriter(new FileWriter("d.txt"));
        BufferedReader reader = new BufferedReader(new FileReader("a.txt"));
        String line=reader.readLine();
        while (line!=null) {
            writer.write(line);
            writer.newLine();
            writer.flush();
        }
        writer.close();
        reader.close();
    }
}

综合

1.把集合中的数据存储到文本文件

案例演示:

需求:把ArrayList集合中的字符串数据存储到文本文件

public class Demo2 {
    //创建一个ArrayList集合
    //添加元素
    //创建一个高效的字符输出流对象
    //遍历集合,获取每一个元素,把这个元素通过高效的输出流写到文本文件中
    //释放资源
    public static void main(String[] args) throws IOException {
        ArrayList<String> list = new ArrayList<>();
        list.add("zhangsan");
        list.add("lisi");
        list.add("wangeu");
        BufferedWriter writer = new BufferedWriter(new FileWriter("a.txt"));
        for (String s : list) {
            writer.write(s);
            writer.newLine();
            writer.flush();
        }
        writer.close();
    }
}

2.把文本文件中的数据存储到集合中

案例演示:

需求:从文本文件中读取数据(每一行为一个字符串数据)到集合中,并遍历集合

public class Demo1 {
    public static void main(String[] args) throws IOException {
        ArrayList<String> list = new ArrayList<>();//创建一个集合
        BufferedReader reader = new BufferedReader(new FileReader("a.txt"));//创建一个高效的字符传输流
        String line=null;//用来记录所查找的字符串
        while ((line=reader.readLine())!=null){
            //如果判断下一行存在字符串,则将读到的字符串添加到集合中
            list.add(line);
        }
        reader.close();
        for (String s : list) {
            System.out.println(s);
        }
        //集合的遍历
    }
}

3.随机获取文本文件中的姓名

案例演示:

需求:我有一个文本文件,每一行是一个学生的名字,请写一个程序,每次允许随机获取一个学生名称

创建一个高效的字符输入流对象
创建集合对象
读取数据,把数据存储到集合中
产生一个随机数,这个随机数的范围是 0 - 集合的长度 . 作为: 集合的随机索引
根据索引获取指定的元素
输出
释放资源
public class Demo2 {
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new FileReader("a.txt"));
        Random random = new Random();
        ArrayList<String> list = new ArrayList<>();
        String len=null;
        while ((len=reader.readLine())!=null){
            list.add(len);
        }
        reader.close();
        int num = random.nextInt(list.size());
        System.out.println(list.get(num));
    }
}

4.复制多级文件夹

案例演示:

public class Demo3 {
    public static void main(String[] args) throws IOException {
        File sourcefile = new File("C:\\Users\\Administrator\\Desktop\\测试图片");
        File aimfile = new File("E:\\测试图片");
        CopyFile(sourcefile, aimfile);
    }
    private static void CopyFile(File sourcefile, File aimfile) throws IOException {
        if (!aimfile.exists()) {
            aimfile.mkdirs();
            File[] listFiles = sourcefile.listFiles();
            for (File listFile : listFiles) {
                if (listFile.isFile()) {
                    FileInputStream in = new FileInputStream(listFile);
                    File file = new File(aimfile, listFile.getName());
                    FileOutputStream out = new FileOutputStream(file);
                    int len=0;
                    byte[] bytes = new byte[1024 * 8];
                    while ((len=in.read(bytes))!=-1){
                        out.write(bytes,0,len);
                        out.flush();
                    }
                    in.close();
                    out.close();
                }else {
                    File file = new File(aimfile, listFile.getName());
                    CopyFile(listFile,file);
                }
            }
        }
    }
}

5.复制指定目录下指定后缀名的文件并修改名称

案例演示:

public class Demo3 {
    public static void main(String[] args) throws IOException {
        File sourcefile = new File("C:\\Users\\Administrator\\Desktop\\测试图片");
        File aimfile = new File("E:\\测试图片");
        CopyFile(sourcefile, aimfile);
    }

    private static void CopyFile(File sourcefile, File aimfile) throws IOException {
        if (!aimfile.exists()) {
            aimfile.mkdirs();
            File[] listFiles = sourcefile.listFiles();
            for (File listFile : listFiles) {
                if (listFile.isFile()) {
                    FileInputStream in = new FileInputStream(listFile);
                    String name = listFile.getName();
                    if (name.endsWith(".jpg")) {
                        name = name.replace(".jpg", ".png");
                    }
                    //更改后缀名
                    File file = new File(aimfile, name);
                    FileOutputStream out = new FileOutputStream(file);
                    int len = 0;
                    byte[] bytes = new byte[1024 * 8];
                    while ((len = in.read(bytes)) != -1) {
                        out.write(bytes, 0, len);
                        out.flush();
                    }
                    in.close();
                    out.close();
                } else {
                    File file = new File(aimfile, listFile.getName());
                    CopyFile(listFile, file);
                }
            }
        }
    }
}

6.键盘录入学生信息按照总分排序并写入文本文件

案例演示:

需求:键盘录入3个学生信息(姓名,语文成绩(chineseScore),数学成绩(mathScore),英语成绩(englishScore)),按照总分从高到低存入文本文件

创建一个学生类: 姓名,语文成绩,数学成绩,英语成绩
因为要排序,所以需要选择TreeSet进行存储学生对象
键盘录入学生信息,把学生信息封装成一个学生对象,在把学生对象添加到集合中
创建一个高效的字符输出流对象
遍历集合,把学生的信息写入到指定的文本文件中
释放资源

public Student() {
    }

    public int totallyScore() {
        return yuScore+sxScore+yyScore;
    }

    public Student(String name, int yuScore, int sxScore, int yyScore) {
        this.name = name;
        this.yuScore = yuScore;
        this.sxScore = sxScore;
        this.yyScore = yyScore;
    }

    public String getName() {
        return name;
    }

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

    public int getYuScore() {
        return yuScore;
    }

    public void setYuScore(int yuScore) {
        this.yuScore = yuScore;
    }

    public int getSxScore() {
        return sxScore;
    }

    public void setSxScore(int sxScore) {
        this.sxScore = sxScore;
    }

    public int getYyScore() {
        return yyScore;
    }

    public void setYyScore(int yyScore) {
        this.yyScore = yyScore;
    }
}
public class Demo4 {
    public static void main(String[] args) throws IOException {
        BufferedWriter writer = new BufferedWriter(new FileWriter("d.txt",true));
        TreeSet<Student> treeSet = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                int num=s1.totallyScore()-s2.totallyScore();
                int num2=num==0?s1.getName().compareTo(s2.getName()):num;
                return -num2;
            }
        });
        System.out.println("-----------欢迎使用本系统---------");
        for (int i = 1; i <= 3; i++) {
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入第" + i + "个的姓名");
            String name = sc.nextLine();
            System.out.println("请输入第" + i + "个人的语文成绩");
            int yuwen = sc.nextInt();
            System.out.println("请输入第" + i + "个人的数学成绩");
            int shuxue = sc.nextInt();
            System.out.println("请输入第" + i + "个人的英语成绩");
            int yingyu = sc.nextInt();
            Student student = new Student(name, yuwen, shuxue, yingyu);
            treeSet.add(student);
        }
        writer.write("-------------成绩单---------------");
        writer.newLine();
        writer.flush();
        writer.write("编号"+"\t"+"姓名"+"\t"+"语文"+"\t"+"数学"+"\t"+"英语"+"\t"+"总分");
        writer.newLine();
        writer.flush();
        int index=1;
        for (Student student : treeSet) {
            writer.write(index+"\t"+student.getName()+"\t"+student.getYuScore()+"\t"+student.getSxScore()+"\t"+student.getYyScore()+"\t"+student.totallyScore());
            writer.newLine();
            writer.flush();
            index++;
        }
        writer.close();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值