IO流

IO流

  1. File 文件操作

  2. IO流

    IO: input和output

    System.in

    System.out

文件流

处理流:

​ 带有缓冲区的流

​ 转换流

​ 对象流

File类

File类:表示一个文件或者文件夹

import java.io.File;

public class Test {
    public static void main(String[] args) {
        try {
//            File file = new File("abc/def/吼吼吼.txt");
//            file.createNewFile(); // 创建一个文件,不包含文件夹
//            System.out.println(file.getParentFile()); // 拿到上一层文件夹的对象
//            System.out.println(file.getParent()); // 拿到文件名
//
//            file.mkdir(); // 创建文件夹,只能创建一个
//            file.mkdirs(); // 创建多级文件夹一定选这个,可以帮我们把上级目录创建出来
//            file.renameTo(new File("abv/def/吼吼吼.txt")); // 重命名
//            file.delete(); // 删除文件
            // 查看相关
//            System.out.println(file.exists()); // 查看文件是否存在
//            System.out.println(file.isAbsolute()); // 判断是否绝对路径
//            System.out.println(file.isDirectory()); // 查看文件是否是文件夹
//            System.out.println(file.isFile()); // 判断文件是否是文件
//            System.out.println(file.length()); // 查看文件大小
//            System.out.println(file.getName()); // 查看文件名
            // 创建文件完整步骤
            File file = new File("abc/def/吃饭.txt");
            // 1.先判断上层文件夹是否存在
            File parentFile = file.getParentFile();
            if (!parentFile.exists()){
                parentFile.mkdirs(); // 创建多级文件夹
            }
            // 2.创建文件
            file.createNewFile();
        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

运行结果:

IO流-节点流

流的分类:

  1. 按照读写的方向来讲,分类输入流和输入出流,站在程序的角度去分析

  2. 按照读写内容的单位来讲,分为字节流和字符流

  3. 按照流的功能不同,分为节点流和处理流

    ​ 节点流:直接连接在文件上的

    ​ 处理流:套在其他流上的

输入 输出
字节流 InputStream OutputStream
字符流 Reader Writer

文件流

FileInputStream:文件字节输入流

import java.io.File;
import java.io.FileInputStream;

public class TestFileInputStream {
    public static void main(String[] args) throws Exception{
        // 创建流
        FileInputStream fis = new FileInputStream(new File("a.txt"));
//        int b = fis.read();
//        System.out.println((char)b); // 读取
//        int b1 = fis.read();
//        System.out.println((char)b1);
//        byte[] bs = new byte[1024];
//        int len = fis.read(bs); // 返回读取了多少个字节
//        System.out.println(new String(bs,0,len));
        // 读取文件最重要的一套写法
        byte[] bytes = new byte[1024]; // 读取1024字节
        int len = 0;
        // 只限在读文件这么写判断
        while((len=fis.read(bytes))!=-1) {
            String s = new String(bytes,0,len);
            System.out.println(s);
        }
        fis.close();
    }
}

运行结果:

​ FileOutputStream:文件字节输出流

import java.io.File;
import java.io.FileOutputStream;


public class TestFileOutputStream {
    public static void main(String[] args) throws Exception{
        // 加上true 不清空原数据
        FileOutputStream fos = new FileOutputStream(new File("a.txt"),true);
        fos.write("谁都很帅".getBytes());
        // 好习惯
        fos.flush(); // 刷新
        fos.close(); // 关闭
    }
}

运行结果:

​ FileReader:文件字符输入流

import java.io.File;
import java.io.FileReader;

public class TestFileReader {
    public static void main(String[] args) throws Exception{
        FileReader fr = new FileReader(new File("a.txt"));
//        int i = fr.read(); // 以字符为单位
//        System.out.println((char)i);

//        char[] cs = new char[1024];
//        int len = fr.read(cs);
//        System.out.println(new String(cs,0,len));

        char[] cs = new char[1024];
        int len = 0;

        while ((len= fr.read(cs))!=-1){
            System.out.println(new String(cs,0,len));
        }
        // 读取不用刷新
        fr.close();
    }
}

运行结果:

​ FileWriter:文件字符输出流

import java.io.File;
import java.io.FileWriter;

public class TestFileWrite {
    public static void main(String[] args) throws Exception{
        FileWriter fw = new FileWriter(new File("a.txt"),true);
        //        fw.write("\r\n"); 换行
        fw.write("我能写字符串了,哎哟,不错哦");

        fw.flush();
        fw.close();
    }
}

运行结果:

如何选择流:

​ 字符流:读取文件中的文字信息

​ 字节流:读取非文本文件的时候

练习:剪切图片从d盘到f盘

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class Test {
    public static void main(String[] args) throws Exception{
        File f = new File("D:/hsq.jpg");
        FileInputStream fis = new FileInputStream(f);
        FileOutputStream fos = new FileOutputStream(new File("F:/hsq.jpg"));

        byte[] bs = new byte[1024];

        int len = 0;
        while ((len=fis.read(bs))!=-1){
            fos.write(bs,0,len);
        }
        fis.close();
        fos.flush();
        fos.close();
        f.delete();
    }
}

缓冲流

带有缓冲区的数据流

BufferedInputStream

BufferedOutputStream

BufferedReader 重点(其他了解就行)

import java.io.*;

public class Test {
    public static void main(String[] args) throws Exception{
//        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("a.txt")));
        BufferedReader br = new BufferedReader(new FileReader(new File("a.txt")));

//        System.out.println(br.readLine()); // 是读取文本文件最好用的方法
//        System.out.println(br.readLine()); // 读取一行
        // 标准写法
        String str = "";
        while ((str= br.readLine())!=null){ // 读取内容
            System.out.println(str);
        }
        br.close();
    }
}

运行结果:

BufferedWriter

转换流

字节流->字符流

InputStreamReader

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Test {
    public static void main(String[] args) throws Exception{
        // 把字节流转换成字符流
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String s = br.readLine();
        System.out.println("从System.in接受到的是:"+s);
    }
}

运行结果:

OutputStreamWriter

import java.io.OutputStreamWriter;
import java.io.Writer;

public class Test2 {
    public static void main(String[] args) throws Exception{
        Writer writer = new OutputStreamWriter(System.out);
        writer.write("你好啊");
        writer.flush();
        writer.close(); // 有时候,这个流不可以关,关了后续无法打印
        System.out.println("看看");
    }
}

运行结果:

对象流

ObjectInputStream

定义一个类

import java.io.Serializable;

public class Person implements Serializable {
    private int id;
    private int age;
    private String name;

    public Person(int id, int age, String name) {
        this.id = id;
        this.age = age;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class Test {
    public static void main(String[] args) throws Exception{
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("person.dat")));
        Person p = new Person(1,18,"劲夫");
        oos.writeObject(p);
        oos.flush();
        oos.close();
    }
}

ObjectOutputStream

import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class Test2 {
    public static void main(String[] args) throws Exception{
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("person.dat")));
        Object obj = ois.readObject();
        Person p = (Person) obj;
        System.out.println(p.getName());
    }
}

运行结果:

// 出现异常 这个是没有序列化

Exception in thread "main" java.io.NotSerializableException: com.wg.io.obj.Person
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at com.wg.io.obj.Test.main(Test.java:11)

序列化:把一个对象转化成字节的过程

反序列化:把字节转换成对象

在Java中只需要给类添加一个实现 Serializable,就是可以被序列化的一个类了

文件修改操作

把文件唐诗三百首.txt,文件中的李白替换李太白

唐诗三百首
1.静夜思,李白。床前明月光,疑是地上霜。举头望明月,低头思故乡。
2.望庐山瀑布,李白。日照香炉生紫烟,遥看瀑布挂前川。飞流直下三千尺,疑是银河落九天。
3.早发白帝城,李白。朝辞白帝彩云间,千里江陵一日还。两岸猿声啼不住,轻舟已过万重山。

结果:

唐诗三百首
1.静夜思,李太白。床前明月光,疑是地上霜。举头望明月,低头思故乡。
2.望庐山瀑布,李太白。日照香炉生紫烟,遥看瀑布挂前川。飞流直下三千尺,疑是银河落九天。
3.早发白帝城,李太白。朝辞白帝彩云间,千里江陵一日还。两岸猿声啼不住,轻舟已过万重山。

思路:逐行读取文件中的内容,依据内容进行替换,把替换的结果记录在一个新文件里,知道数据写入完毕,把源文件删除,把新文件的名字改成源文件的名字。

import java.io.*;

public class Test {
    public static void main(String[] args) throws Exception{
        File res = new File("唐诗三百首.txt");
        File another = new File("副本_唐诗三百首.txt");
        BufferedReader br = new BufferedReader(new FileReader(res));
        BufferedWriter bw = new BufferedWriter(new FileWriter(another));
        String line = "";
        while ((line = br.readLine())!=null){ // 读取数据
            line = line.replace("李白","李太白"); // 替换数据
            bw.write(line); // 写入到新文件
            bw.newLine(); // 另起一行
        }
        br.close();
        bw.flush();
        bw.close();
        // 删除源文件
        res.delete();
        another.renameTo(res); // 重命名
    }
}

练习

读取文件中的水果信息,计算水果的总价(价格*库存),并写入到文件中

fruit.txt:

名称_价格_库存
香蕉_3.33_20
苹果_1.25_10
橘子_1.33_40

结果:

名称_价格_库存_总价
香蕉_3.33_20_66.60_66.60
苹果_1.25_10_12.50_12.50
橘子_1.33_40_53.20_53.20
import java.io.*;
import java.text.DecimalFormat;

public class HomeWork {
    public static void main(String[] args) throws Exception{
        DecimalFormat df = new DecimalFormat(".00");
        // 1 能从文件中读取水果信息
        // 1.1 需要创建输入流 BufferedReader
        // 1.2 第一行需要特殊处理,第一行是表头
        File f1 = new File("fruit.txt");
        BufferedReader br = new BufferedReader(new FileReader(f1));

        File f2 = new File("副本_fruit.txt");
        BufferedWriter bw = new BufferedWriter(new FileWriter(f2));

        String title = br.readLine(); // 第一个行内容
        // 写出第一行内容
        bw.write(title+"_总价");
        bw.newLine();
        // 2 计算水果的总价格
        // 2.1 读取所有水果信息
        String content = "";
        while ((content = br.readLine())!=null){
            String[] fs = content.split("_");

            double price = Double.parseDouble(fs[1]); // 因为是小数,转换成double
            double num = Double.parseDouble(fs[2]);
            double totle = price * num;
            String totleSrt = df.format(totle); // "66.60"

            content += "_"+totleSrt; // 拼接 香蕉_3.33_20_66.60
            bw.write(content); // 向新文件写入内容
            bw.newLine();
        }
        br.close();
        bw.flush();
        bw.close();
        // 3 删除源文件,重命名新文件
        f1.delete();
        f2.renameTo(f1);
    }
}
posted @ 2021-05-18 21:15  闲着的大叔  阅读(46)  评论(0编辑  收藏  举报