Java IO流要点概述

1、流的本质

在这里插入图片描述

2、常见的16个流:

java语言中的流分为四大家族:InputStream、OutputStream、Reader、Writer
2.1、文件相关

  • FileInputStream
  • FileOutputStream
  • FileReader
  • FileWriter
    2.2、带缓冲区的
  • BufferedInputStream
  • BufferedOutputStream
  • BufferedReader
  • BufferedWriter
    2.3、数据流
  • DataInputStream
  • DataOutputStream
    2.4、对象流
  • ObjectInputStream
  • ObjectOutputStream
    2.5、转换流(字节流转换为字符流)
  • InputStreamReader
  • OutputStreamWriter
    2.6、标准输出流
  • PrintWriter
  • PrintStream// 标准的输出流(默认输出到控制台)

3、常用16个流的结构关系

  • InputStream、OutputStream两家子:
    在这里插入图片描述
  • Reader、Writer两家子
    在这里插入图片描述

4、FileInputStream常用方法及原理

应用实例及注解:

/**
 * java.io.InputStram;
 *      java.io.FileInputStream;文件字节输入流
 *  按照字节方式读取文件
 */
public class FileInputStreamTest01 {
    public static void main(String[] args) {
        FileInputStream fis =  null;
        try {
            // 1、要读取某文件,先与这个文件创建一个“输入流”
            // 绝对路径,java中“\”有转义作用使用“\\”代替,如果使用相对路径,是相对于java执行文件来说的,在windows中还可以使用“/”来查找路径
            String filePath01 = "E:\\learing\\temporary\\test01.txt";
            String filePath02 = "E:/learing/temporary/test01.txt";
            fis = new FileInputStream(filePath02);// 在windows环境下filePath01和filePath02均可执行
            
            // 2、读操作
            // 2.1 read()方法每次读取一个字节,结束返回-1。该方法将会频繁的读取磁盘文件,每字节读取一次,效率低。
            // 2.1.1 测试文件内容,“aB我c”,中文占两个字节
            int r1 = fis.read();
            int r2 = fis.read();
            int r3 = fis.read();
            int r4 = fis.read();
            int r5 = fis.read();
            int r6 = fis.read();
            System.out.println(r1);// a-->97
            System.out.println(r2);// B-->96
            System.out.println(r3);// “我”一半-->206
            System.out.println(r4);// “我”另一半-->210
            System.out.println(r5);// c-->99
            System.out.println(r6);// 结束,文件的末尾-->-1
            // 2.1.2 循环获取方式
            System.out.println("==============================================");
            fis = new FileInputStream(filePath02);
            int temp = 0;
            while ((temp = fis.read()) != -1) {
                System.out.println(temp);
            }
            System.out.println("==============================================");
            // 2.2 read(byte[] b)读取前再内存中创建byte[],每次读取多个字节到byte[]中,效率较高,该方法返回int值代表的是,本次读取了多少个字节,末尾返回-1。
            fis = new FileInputStream(filePath02);
            byte[] bts = new byte[3];// 设定初值,每次最多读3个字节
            // 2.2.1 测试文件内容,“aBcdefg”,中文占两个字节,中文此处将会乱码
            int i1 = fis.read(bts);
            System.out.println(new String(bts));// abc
            int i2 = fis.read(bts);
            System.out.println(new String(bts));// def
            int i3 = fis.read(bts);
            System.out.println(new String(bts));// gef
            System.out.println(new String(bts, 0, i3));// g(如果直接输出将输出“gef”因为最后一组只覆盖了一个字节)
            int i4 = fis.read(bts);
            System.out.println(i1);// 3
            System.out.println(i2);// 3
            System.out.println(i3);// 1
            System.out.println(i4);// -1
            System.out.println("==============================================");
            // 2.2.2 循环获取方式1,测试内容"abcdefg"
            byte[] bts1 = new byte[1024];// 设定初值,每次最多读1KB
            fis = new FileInputStream(filePath02);
            while (true) {
                int temp1 = fis.read(bts1);
                if (temp1 == -1) break;
                // 将bts1中有效部分转换为字符串
                System.out.print(new String(bts1, 0, temp1));// abcdefg
            }
            System.out.println("==============================================");
            // 循环方式2,,测试内容"abcdefg"
            int temp2 = 0;
            fis = new FileInputStream(filePath02);
            while ((temp2 = fis.read(bts1)) != -1) {
                System.out.print(new String(bts1, 0, temp2));// abcdefg
            }
            System.out.println("==============================================");
            // 2.2 int available()返回流中剩余的字节数,测试内容"abcdefg"
            fis = new FileInputStream(filePath02);
            System.out.println(fis.available());// 7
            // 2.2 long skip(long)跳过n个字节,从第n个字节后往后读取,测试内容"abcdefg"
            System.out.println(fis.skip(1));
        } catch (FileNotFoundException e){
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 为了保证流一定被关闭,finally块中执行关闭操作
            if(fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

5、FileOutputStream常用方法

/**
 * java.io.OutputStream;
 *      java.io.FileOutputStream 文件字节输出流
 *      将计算机内存的数据写入硬盘中
 */
public class FileOutputStreamTest01 {
    public static void main(String[] args) {
        // 绝对地址位置上生成指定类型的文件
        String filePath02 = "E:/learing/temporary/test02.txt";
        FileOutputStream fos = null;
        try {
            // 不存在则自动创建
	        // fos = new FileOutputStream(filePath02);// 重复调用write()方法,覆盖原文件
            fos = new FileOutputStream(filePath02, true);// 重复调用write()方法,追加写入
            String msg = "Hello world!";
            byte[] byteMsg = msg.getBytes();
            fos.write(byteMsg);// 将数组中的数据全部写入文件
            // fos.write(b, off, len);// 将数组中的数据部分写入文件
            // 为了保证数据完全写入硬盘,需要刷新,强制写入
            fos.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭流
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

6、FileReader简单例子

/**
 * java.lang.Object 
 *   java.io.Reader 
 *       java.io.InputStreamReader 转换流(字节输入流-->字符输入流)
 *           java.io.FileReader 文件字符输入流,用于纯文本文件
 */
public class FileReaderTest01 {
    public static void main(String[] args) {
        String filePath = "E:\\learing\\temporary\\test03.txt";
        FileReader fr = null;
        try {
            fr = new FileReader(filePath);// 创建文件字符输入流
            char[] cbuf = new char[512];// 1KB
            int temp = 0;
            while ((temp = fr.read(cbuf)) != -1) {
                // 将char数组有效部分输出
                System.out.println(new String(cbuf, 0, temp));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭字符输入流
            try {
                if(fr != null) {
                    fr.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

7、FileWriter简单例子

/**
 * 
 * java.lang.Object 
 *   java.io.Writer 
 *       java.io.OutputStreamWriter 转换流(字节输出流-->字符输出流)
 *           java.io.FileWriter 文件字符输出流,用于纯文本文件
 *
 */
public class FileWriterTest01 {
    public static void main(String[] args) {
        FileWriter fw = null;
        String filePath = "E:\\learing\\temporary\\test04.txt";
        try {
            // fw = new FileWriter(filePath);// 覆盖
            fw = new FileWriter(filePath, true);// 追加
            fw.write("让我们荡起双桨!!");// 直接写String
            char[] chars = {'小','船','儿','推','开','波','浪','。','/','n'};
            fw.write(chars, 0, 8);// 写入部分char数组
            fw.write(System.lineSeparator());// 换行
            fw.flush();// 刷新,强制写入
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭
            if (fw != null) {
                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

8、BufferedReader简单例子

/**
 * 带缓存区的
 * 字节
 * BufferedInputStream 
 * BufferedOutputStream 
 * 字符
 * BufferedReader 带缓存区的字符输入流。重点读一行文本readLine()方法,返回字符串。
 * BufferedWriter
 *
 */
public class BufferedReaderTest01 {
    public static void main(String[] args) {
        BufferedReader br = null;
        try {
            // 1.BufferedReader(Reader in)新建BufferedReader时需要传入一个Reader,FileReader可以向上转型为Reader
            // br = new BufferedReader(new FileReader("E:\\learing\\temporary\\file.java"));
            // 2.如果手上有的是一个文件字节流FileInputStream,可以先把FileInputStream用转换流InputStreanReader转换为文件字符流,InputStreanReader向上转型为Reader
            br = new BufferedReader(new InputStreamReader(new FileInputStream("E:\\learing\\temporary\\file.java")));
            String temp = null;// 用于接收readLine()返回值
            while ((temp = br.readLine()) != null) {
                System.out.println(temp);// 输出一行,但是行尾不带换行符
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();// 关闭最外层的流即可(主使者模式)
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

9、BufferedWriter简例

public class BufferedWriterTest01 {
    public static void main(String[] args) {
        BufferedWriter bw = null;
        try {
            // BufferedWriter构造方法需要传入一个Reader
            // 1.直接传入一个FileWriter
            // bw = new BufferedWriter(new FileWriter("E:\\learing\\temporary\\test05.txt"));
            // 使用OutputStreamWriter将FileOutoutStream转换为FileWriter再传入FileWriter构造方法
            bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("E:\\learing\\temporary\\test05.txt",true)));
            bw.write("重庆麻辣烫!");// 写入
            bw.newLine();// 写入一个换行符
            bw.write("谁吃谁知道!");// 写入
            bw.newLine();// 写入一个换行符
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

10、PrintStream标准的输出流

简例:

/**
 * java.io.PrintStream; 标准的输出流,默认打印到控制台,以字节方式
 * java.io.prinWriter; 以字符方式
 *
 */
public class PrintStreamTest01 {
    public static void main(String[] args) {
        // 默认是输出到控制台
        System.out.println("展示在控制台1!");
        // 以上代码也可以这样写
        PrintStream ps = System.out;
        ps.println("展示在控制台2!");
        try {
            // 可以改变流的输出方向,如下
            System.setOut(new PrintStream(new FileOutputStream("E:\\learing\\temporary\\log.txt")));
            // 后面的输出将输出到log文件中,可以使用该方法记录日志
            System.out.print("展示再log文件中1!");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

11、ObjectOutputStream和ObjectInputStream:序列化/反序列化流

ObjectOutputStream序列化简例:

/**
 * java.io.Serializable;该接口是一个可序列化的,接口没有任何方法,是一个标识接口。像这样的接口还有java.lang.Cloneable可克隆的
 *
 * 标识接口,起到标识的作用
 * JVM如果看到该对象实现了某个标识接口,会对他特殊待遇:
 * 会给该类添加一个属性,static final long serialVersionUID = 321315465488898
 * 当类改变重新编译后,序列号也会改变,将导致反序列化失败。
 * 为了保证该类升级后序列号和旧版一致,可以自己写一个序列化版本号。
 */
public class User implements Serializable{
    // 如果不想让属性参加序列化,需要使用transient关键字修饰
    // transient String name;
    String name;
    User (String name) {
        this.name = name;
    }
    public String toString() {
        return "User[name="+name+"]";
    }
}

/**
 * java.io.ObjectOutputStream;序列化JAVA对象到硬盘(Serial)
 * java.io.ObjectInputStream;将硬盘中的数据“反序列化”到JVM内存(DeSerial) 
 *
 * Compile 编译(java-->class)
 * DeCompile 反编译(class-->java)
 */
public class ObjectOutputStreamTest01 {
    public static void main(String[] args) {
        // 创建java对象
        User u1 = new User("刘亦菲");
        ObjectOutputStream oos = null;
        try {
            // 创建输出流(序列化流)(JVM中的java对象状态保存到硬盘中)
            oos = new ObjectOutputStream(new FileOutputStream("E:\\learing\\temporary\\test07.txt"));
            // 写
            oos.writeObject(u1);
            // 强制写出
            oos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (oos != null) {
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

对应ObjectInputStream反序列化简例:

public class ObjectInputStreamTest01 {
    public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
        // 创建反序列化流
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\learing\\temporary\\test07.txt"));
        // 反序列化
        Object obj = ois.readObject();
        System.out.println(obj);// 输出:User[name=刘亦菲]
        ois.close();
    }
}

12、File:抽象表示的文件和目录的路径名

常用方法简例:

/**
 * java.io.File;
 *      1、File类和流无关,不能通过该类完成文件的读和写
 *      2、File是文件和目录路径名的抽象表示形式
 * File代表的是硬盘上的Directory和file
 */
public class FileTest01 {
    public static void main(String[] args) throws IOException {
        // 可以是相对路径,也可以使用绝对路径
        File f1 = new File("E:\\learing\\draft");
        File f2 = new File("E:\\learing\\draft\\Test3.java");
        // 判断是否存在exists()
        System.out.println(f1.exists());
        System.out.println(f2.exists());
        // 创建目录mkdir()
        File f3 = new File("E:\\learing\\draft\\util2");
        if (!f3.exists()) {
            f3.mkdir(); 
        }
        // 创建文件createNewFile()
        File f4 = new File("E:\\learing\\draft\\fileTest001.txt");
        if (!f4.exists()) {
            f4.createNewFile(); 
        }
        // 创建多重目录mkdirs()
        File f5 = new File("E:/learing/draft/a/b/c/d");
        if (!f5.exists()) {
            f5.mkdirs(); 
        }
        // 列出子文件
        File f6 = new File("E:\\learing\\draft");
        File[] fs = f6.listFiles();
        for (File f : fs) {
            System.out.println(f.getAbsolutePath());
            // 输出以“**”结尾的
            if (f.getAbsolutePath().endsWith(".java")) {
                System.out.println(">>>>>>>>>>>>>>>>>>>java>>>>>>>>>>>>>>" + f.getAbsolutePath());
            }
        }
        // 使用递归,列出所有子文件及目录
        getFiles(f6);
        
        // 常用的其它方法:
        // boolean  delete() 删除
        // void     deleteOnExit() 存在删除
        // File     getAbsoluteFile() 获取绝对路径
        // String   getName() 获取文件名
        // String   getParent() 获取父路径
        // boolean  isDirectory() 是否路径
        // boolean  isFile() 是否文件
        // long     lastModified() 最后修改时间
        // long     length() 获取文件大小(字节数)
        
    }
    
    public static void getFiles(File file) {
        if (file.isFile()) {// 是文件则不往下查找
            return;
        }
        File[] fs = file.listFiles();// 是目录:输出当前目录,并查询子目录中的文件
        for (File f : fs) {
            System.out.println("getFiles>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + f);
            getFiles(f);// 递归查找目录
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值