WELCOME

任何一个伟大的目标,都有一个微不足道的开始。

Java_I\O流

I/O框架

1.0流的概念

内存与存储设备之间传输数据的通道

image


2.0流的分类

2.1按方向[重点]

  • 输入流:将<存储设备>中的内容读到<内存>中
  • 输出流:将<内存>中的内容写到<存储设备>中

2.2按单位

  • 字节流:以字节为单位,可以读写所有数据
  • 字符流:以字符为单位,只能读写文本数据

2.3按功能

  • 节点流:具有实际传输数据的读写功能
  • 过滤流:在节点流的基础之上增强功能

3.0字节流

字节流的父类(抽象类)

  • InputStream:字节输入流
  • OutputStream:字节输出流
//InputStream 字节输入流
public int read(){}
public int read(byte[] b){}
public int read(byte[] b, int off, int len){}

// OutputStream 字节输出流
public void write(int n){}
public void write(byte[] b){}
public void write(byte[] b, int off, int len){}

3.1文件字节流

  • FilleInputStream:
    • public int read(byte[] b) //从流中读取多个字节,将读到的内容存入b数组中,返回实际 读到的字节数;如果达到文件底部,则返回-1.
package com.io;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

/**
 * 演示FileInputStream的使用
 * 文件字节输入流
 */
public class Demo01 {
    public static void main(String[] args) throws Exception {
        //创建fileInputStream,并指定文件路劲
        FileInputStream fis = new FileInputStream("D:\\aaa.txt");
        //读取文件

        /* 单个字节读取
        int data = 0;
        while ((data = fis.read())!=-1){
            System.out.print(data+" ");
            System.out.println((char) data);
        }
        */
        //一次性读取多个字节
        byte[] bytes = new byte[1024];
        int count = 0;
        while ((count=fis.read(bytes))!=-1){
            System.out.println(new String(bytes,0,count));
        }

        //3.关闭
        fis.close();
        System.out.println("执行完毕");
    }
}

其中new String(bytes,0,count)中bytes - 要解码为字符的字节, offset - 要解码的首字节的索引, length - 要解码的字节数

  • FileOutputStream:
    • public void write(byte[] b) //一次写多个字节,将b数组中所有字节,写入输出流

new FileOutputStream(第一个参数name:存储文件的位置,第二个参数:默认为false(可以不写))(如果为TRUE,则表示在末尾追加,为FALSE则表示覆盖)

package com.io;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;

/**
 * 演示文件字节输出流的使用
 * FileOutputStream
 */
public class Demo02 {
    public static void main(String[] args) throws Exception {
        //1.创建文件字节输出流对象
        FileOutputStream fos = new FileOutputStream("D:\\bbb.txt",true);
        //2.写入文件
        fos.write(97);//会转化成Ascall吗
        fos.write('b');
        fos.write('a');
        String string = "helloworld";
        fos.write(string.getBytes());
        //3.关闭
        fos.close();
        System.out.println("执行完毕");
    }
}

3.2图片复制案例

package com.io;

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

/**
 * 使用文件字节流实现文件复制
 */
public class Demo03 {
    public static void main(String[] args) throws Exception{
        //1.创建流
        //1.1文件字节输入流
        FileInputStream fis = new FileInputStream("D:\\java\\IO\\timg.jpg");
        //1.2文件字节输出流
        FileOutputStream fos = new FileOutputStream("D:\\java\\IO\\timg1.jpg");
        //一边读,一边写
        byte[] bytes = new byte[1024];
        int count = 0;//count 是用来保存实际读取数据
        while ((fis.read(bytes))!=-1){
            fos.write(bytes,0,count);
        }
        //关闭流
        fis.close();
        fos.close();
        System.out.println("复制完毕");

    }
}

3.3字节缓冲流

缓冲流:BufferedInputStream/ BufferedOutputStream

  • 提高IO效率,减少访问磁盘次数
  • 数据存储在缓冲区中,flush是将缓冲区的内容写入文件中,也可以直接close

再补充一下,如果我们写入的文件大小刚好和缓冲区容量一致时,就会自动将文件写入到路径中,如果不满,就需要close或flush;打个比方,文件20k,缓冲10k,如果不使用close或flush

package com.io;

import java.io.BufferedInputStream;
import java.io.FileInputStream;

/**
 * 使用字节缓冲流读取
 * BufferedInputStream
 */
public class Demo04 {
    public static void main(String[] args) throws Exception{
        //1.创建BufferedInputStream
        FileInputStream fis = new FileInputStream("D:\\java\\IO\\aaa.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);

        //2.读取
//        int data = 0;
//        System.out.println((char) bis.read());
//        System.out.println((char)bis.read());
//        while ((data = bis.read())!=-1){
//            /*
//                bis.read()会读入一个字节,然后data = bis.read(),则sout((char)data),则会输出读入的字节
//                因为当读入的字节为最后一个的时候,会返回-1,所以data!=-1的时候,会直接输出读入的字节
//             */
//            System.out.print((char)data);
//        }


        // 用自己创建的缓冲流
        byte[] bytes = new byte[1024];
        int count = 0;
        while ((count = bis.read(bytes))!=-1){
            System.out.println(new String(bytes,0,count));
        }
        //关闭
        bis.close();
    }
}

package com.io;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;

/**
 *使用字节缓冲流写入文件
 * BufferedOutputStream
 */
public class Demo05 {
    public static void main(String[] args) throws Exception {
        //1.创建字节输出缓冲流
        FileOutputStream fos = new FileOutputStream("D:\\java\\IO\\buffer.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        //2.写入文件
        for (int i = 0;i<10;i++){
            bos.write("helloworld \r\n".getBytes());//先写入缓冲区
            bos.flush();//刷新到硬盘
        }

        //3.关闭(内部会调用fiush方法)
        bos.close();
    }
}

4.0对象流

ObjectOutputStream / ObjectInputStream
  • 增强了缓冲区功能
  • 增强了读写8种基本数据类型和字符串的功能
  • 增强了读写对象的功能
    • readObject() 从流中读取一个对象
    • writeObject(Object obj) 向流中写入一个对象

使用流传输对象的过程称为序列化、反序列化

5.0序列化与反序列化

package com.io;

import java.io.Serializable;

/**
 * 学生类
 */

//Serializable :可序列化
//implements Serializable是一个标记接口,仅仅是告诉我们Student类可以序列化
public class Student implements Serializable {
    private String name;
    private int age;

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

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

}

5.1序列化

package com.io;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

/**
 *使用ObjectOutputStream实现对象序列化
 * 要求:序列化类必须实现Serializable接口
 */
public class Demo06 {
    public static void main(String[] args) throws Exception{
        //1.创建对象流
        FileOutputStream fos = new FileOutputStream("D:\\java\\IO\\stu.bin");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        //2.实现序列化(写入操作)
        Student zhangsan = new Student("zhangsan", 20);
        oos.writeObject(zhangsan);
        //3.关闭
        oos.close();
        System.out.println("序列化完毕");

    }
}

5.2反序列化

package com.io;

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

/**
 * 使用ObjectInputStream实现反序列化
 *
 */
public class Demo07 {
    public static void main(String[] args) throws Exception{
        //1.创建对象流
        FileInputStream fis = new FileInputStream("D:\\java\\IO\\stu.bin");
        ObjectInputStream ois = new ObjectInputStream(fis);
        //2.读取文件(反序列化)
        Student s = (Student) ois.readObject();
        //3.关闭
        ois.close();
        System.out.println("执行完毕");
        System.out.println(s.toString());
    }
}

5.3注意事项

  1. 某个类要想序列化必须实现Serializable接口
  2. 序列化类中对象属性要求实现Serializable接口
  3. 序列化版本号ID,保证序列化的类和反序列化的类是同一个类
  4. 使用transient修饰属性,这个属性就不能序列化 transient:瞬间的
  5. 静态属性不能序列化
  6. 序列化多个对象,可以借助集合来实现

6.0编码方式

UTF-8,GBK...

7.0字符流

7.1字符流的父类(抽象类)

reader 字符输入流

  • public int read(){}
  • public int read(char[] c){}
  • public int read(char[] b, int off, int len){}

Writer 字符输出流

  • public void write(int n){}
  • public void write(String str){}
  • public void write(char[] c){}

7.2文件字符流

  • FileReader:
    • public int read[char[] c] //从流中读取多个字符,将读到的内容存到c数组中,返回实际读到的字符数;如果达到文件底部,则返回-1
package com.io.demo;

import java.io.FileReader;

/**
 * 使用FileReader读取文件
 *
 */
public class Demo08 {
    public static void main(String[] args) throws Exception{
        //1.创建FileReader 文件字符输入流
        FileReader fr = new FileReader("D:\\java\\IO\\hello.txt");
        //2读取
        //2.1单个字符读取
//        int data = 0;
//        while ((data = fr.read())!=-1){
//            System.out.print((char) data); // 读取一个字符
//        }
        //2.2
        char[] chars = new char[1024];// 字符缓冲区读取
        int count = 0;
        while ((count = fr.read(chars))!=-1){
            System.out.println(new String(chars,0,count));
        }
        //3关闭
        fr.close();
    }
}
  • FileWriter:
    • public void write(String str) //一次写入多个字符,将b数组中所有字符写入输出流
package com.io.demo;

import java.io.FileWriter;

/**
 * 使用FileWriter 写入文件
 */
public class Demo09 {
    public static void main(String[] args) throws Exception{
        //1.创建FileWriter对象
        FileWriter fw = new FileWriter("D:\\java\\IO\\write.txt");
        //2.写入
        for (int i = 0;i<10;i++) {
            fw.write("Java是世界上最好的语言\r\n");
            fw.flush();
        }


        //3.关闭
        fw.close();
        System.out.println("执行完毕");
    }
}

7.3(案例)使用上述内容进行文件文本复制

字符流不能复制图片或二进制文件,使用字节流可以复制任意文件

package com.io.demo;

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

/**
 * 使用FileReader 与 FileWriter复制文本文件,不能复制二进制数据
 */
public class Demo10 {
    public static void main(String[] args) throws Exception{
        //1.使用FileReader 与 FileWriter
        FileReader fr = new FileReader("D:\\java\\IO\\write.txt");
        FileWriter fw = new FileWriter("D:\\java\\IO\\write2.txt");

        //2.读写
        int data = 0;
        while ((data = fr.read())!=-1){
            fw.write(data);
            fw.flush();
        }

        //3.关闭
        fr.close();
        fw.close();
        System.out.println("复制完毕");
    }
}

7.4字符缓冲流

  • 缓冲流:BufferedReader / BufferedWriter
    • 高效读写
    • 支持输入换行符
    • 可一次写一行读一行

1.BufferedReader

package com.io.demo;

import java.io.BufferedReader;
import java.io.FileReader;

/**
 * 使用字符缓冲流读取文件
 * BufferedReader
 */
public class Demo11 {
    public static void main(String[] args) throws Exception{
        //创建缓冲流
        FileReader fr = new FileReader("D:\\java\\IO\\write.txt");
        BufferedReader br = new BufferedReader(fr);

        //读取
        //第一种方式
//        char[] chars = new char[1024];
//        int count = 0;
//        while ((count = br.read(chars))!=-1){
//            System.out.print(new String(chars,0,count));
//        }
        //第二种方式:一行一行读
        String line = null;
        while ((line = br.readLine())!=null){
            System.out.println(line);
        }

        //关闭
        br.close();
    }
}

2.BufferedWriter

package com.io.demo;

import java.io.BufferedWriter;
import java.io.FileWriter;

/**
 * 使用BufferedWriter的使用
 */
public class Demo12 {
    public static void main(String[] args) throws Exception{
        //1.创建BufferedWrite对象
        FileWriter fw = new FileWriter("D:\\java\\IO\\bw.txt");
        BufferedWriter bw = new BufferedWriter(fw);

        //2.写入
        for (int i=0;i<10;i++){
            bw.write("好好学习,天天向上");
            bw.newLine(); //写入一个换行符,相当于 \r\n
            bw.flush();
        }

        //3.关闭
        bw.close();
        System.out.println("执行完毕");
    }
}

7.5PrintWrite

封装了print() / println() 方法 支持写入后换行

支持数据原样打印

package com.io.demo;

import java.io.PrintWriter;

/**
 * PrintWriter的使用
 */
public class Demo13 {
    public static void main(String[] args) throws Exception{
        //1.创建打印流
        PrintWriter pw = new PrintWriter("D:\\java\\IO\\print.txt");
        //2.打印
        pw.println(100);
        pw.println(3.14);
        pw.println(true);
        pw.println("abc");
        pw.println('你');
        //3.关闭
        pw.close();
        System.out.println("执行完毕");
    }
}

7.6转换流

桥转换流 InputStreamReader / OutputStreamWriter

可将字节流转换为字符流

可设置字符的编码方式

1.InputStreamReader

package com.io.demo;

import java.io.FileInputStream;
import java.io.InputStreamReader;

/**
 * InputStreamReader读取文件,可以指定使用的编码
 */
public class Demo14 {
    public static void main(String[] args) throws Exception{
        //创建InputStreamReader对象
        FileInputStream fis = new FileInputStream("D:\\java\\IO\\write.txt");
        InputStreamReader isr = new InputStreamReader(fis, "utf-8");
        //读取文件
        int data = 0;
        while ((data = isr.read())!=-1){
            System.out.print((char)data);
        }

        //关闭
        isr.close();
    }
}

2.OutputStreamWriter

package com.io.demo;

import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

/**
 * 使用OutputStreamWriter写入文件,可以指定编码
 */
public class Demo15 {
    public static void main(String[] args) throws Exception{
        //创建OutputStreamWriter
        FileOutputStream fos = new FileOutputStream("D:\\java\\IO\\info.txt");
        OutputStreamWriter osw = new OutputStreamWriter(fos,"GBK");

        //写入
        for (int i=0;i<10;i++){
            osw.write("我是你爸爸\r\n");
            osw.flush();
        }

        //关闭
        osw.close();
        System.out.println("执行完毕");
    }
}

8.0 File类

  • 概念:代表物理盘符中的一个文件或者文件夹
  • 方法:
    • createNewFile() //创建一个新文件
    • mkdir() //创建一个新目录
    • delete() //删除文件或空目录
    • exists() //
    • getAbsolutePath() //获取文件的绝对路径
    • getName() //取得名字
    • getParent() //获取文件/目录所在目录
    • isDirectory() //是否Wie目录
    • isFile() //是否为文件
    • length() //获取文件长度
    • listFiles() //列出目录中的所有内容
    • renameTo() //修改文件名为

8.1文件操作

package com.io.demo;

import java.io.File;
import java.util.Date;

/**
 * File类的使用
 * (1)分隔符
 * (2)文件操作
 * (3)文件夹操作
 */
public class Demo16 {
    public static void main(String[] args) throws Exception{
        separator();
        fileOpen();
    }
    //(1)分隔符
    public static void separator(){
        System.out.println("路径分隔符"+ File.pathSeparator);
        System.out.println("名称分隔符"+ File.separator);
    }
    //(2)文件操作
    public static void fileOpen() throws Exception{
        //1.创建文件
        File file = new File("D:\\java\\IO\\file.txt");
        if (! file.exists()){ //exists()方法,判断文件是否存在
            boolean b = file.createNewFile();//createNewFile()方法:如果文件创建成功,返回true,否则返回false
            System.out.println("创建结果:"+b);
        }
        //2.删除文件
        //2.1直接删除
//        System.out.println("删除结果:"+file.delete());

        //2.2 使用jvm退出删除
//        file.deleteOnExit();

        //3.获取文件信息
        System.out.println("获取绝对路径" + file.getAbsolutePath());
        System.out.println("获取路径" + file.getPath());
        System.out.println("获取文件名称" + file.getName());
        System.out.println("获取夫目录" + file.getParent());
        System.out.println("获取文件长度" + file.length());

        //判断
        System.out.println("是否可写:"+file.canWrite());
        System.out.println("是否是文件:"+file.isFile());
        System.out.println("是否隐藏:"+file.isHidden());
    }
}

8,2文件夹操作

//(3)文件夹操作
public static void directoryOpen() {

    //1.创建文件夹
    File file = new File("D:\\java\\aaa\\bbb");
    System.out.println(file.toString());
    if (!file.exists()){
//        file.mkdirs();//只能创建单级目录
        System.out.println("创建结果:"+file.mkdirs());//创建多级目录

    }
    //2.删除文件夹
    //2.1直接删除
    //只删除最里面的那个目录,而且该目录必须是空目录
//    System.out.println("删除结果:"+file.delete());

    //3.获取文件夹信息
    System.out.println("获取绝对路径" + file.getAbsolutePath());
    System.out.println("获取路径" + file.getPath());
    System.out.println("获取文件名称" + file.getName());
    System.out.println("获取父目录" + file.getParent());
    System.out.println("获取文件长度" + file.length());
    //4.判断
    System.out.println("判断是否为文件夹:"+file.isDirectory());
    System.out.println("是否隐藏:"+file.isHidden());
    //5.遍历文件夹
    File file1 = new File("D:\\图片");
    String[] list = file1.list();
    System.out.println("================================");
    for (String s:list){
        System.out.println(s);
    }

8.3FileFilter 接口


  • public interface FileFilter

    • boolean accept(File pathname)
  • 但调用File类中的listFiles()方法时,支持传入FileFilter接口实现类,对获取文件进行过滤,只有满足条件的文件才可以出现在listFiles()的返回值中

 System.out.println("-------------FileFilter接口的使用--------------");
    File[] files = file1.listFiles(new FileFilter() {
        @Override
        public boolean accept(File pathname) {
            if (pathname.getName().endsWith(".png")) {
                return true;
            }
            return false;
        }
    });
    for (File f:files){
        System.out.println(f.getName());
    }

8.4递归遍历文件夹

package com.io.demo;

import java.io.File;

/**
 * 案例1:递归遍历文件夹
 */
public class ListDemo {
    public static void main(String[] args) {
        listDir(new File("D:\\java"));
    }
    public static void listDir(File directory){
        File[] files = directory.listFiles();
        System.out.println(directory.getAbsolutePath());
        if (files!=null && files.length>0){
            for (File file:files){
                if (file.isDirectory()){
                    listDir(file);//递归
                }
                else {
                    System.out.println(file.getAbsolutePath());
                }
            }
        }
    }
}

8.5递归删除文件夹

public static void deleteDir(File dir){
  File[] files = dir.listFiles();
  if(files != null && files.length > 0){
    for(File file : files){
      if(file.idDirectory()){
        deleteDir(file); // 递归
      }else{
        // 删除文件
        sout(file.getAbsolutePath() + "删除" + file.delete());
      }
    }
  }
}

9.0 Properties

  • Properties:属性集合
  • 特点:
    • 1.存储属性名和属性值
    • 2.属性名与属性值都是字符串类型
    • 3.没有泛型
    • 4.和流有关
posted @ 2021-08-22 14:20  GD1_1DG  阅读(55)  评论(0)    收藏  举报
Language: HTML