【学习笔记】JAVA I/O框架

1. 什么是流?

链接
动画连接
概念: 内存与存储设备之间传输数据的通道
数据借助流传输

2. 流的分类:

按方向:
输入流:将存储设备的内容读到内存中
输出流:将内存中内容写入到存储设备中
按单位:
字节流:以字节为单位,可以读写所有数据
字符流:以字符为单位,只能读写文本数据
按功能:
节点流:具有实际传输数据的读写功能。
过滤流:在节点流的基础之上增强功能。

3 字节流

在这里插入图片描述

3.1 FileInputSteam的使用(文件字节流的使用)

InputStream的子类

FileInputStream:
public int read(byte[]b)//从流中读取多个字节,将读到内容存入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1。
FileOutputStream:
public void write(byte[]b)//一次写多个字节,将b数组中所有字节,写入输出流。

package javaOfIO;

import java.io.FileInputStream;

/**
 * 演示FileInputStream的使用
 * 文件字节输入流
 */
public class MyFileInputStream {
    public static void main(String[] args) throws Exception{
        // 1. 创建FileInputStream, 并指定文件路径
        FileInputStream fileInputStream = new FileInputStream("d:\\aaa.txt");
        // 2. 读取文件
        // 2.1 单个字符读取
//        int read = fileInputStream.read();
//        int data = 0;
//        while((data = fileInputStream.read()) != -1){
//            System.out.println((char)data);
//        }
        // 2.2 一次读取多个字节
//        System.out.println("======一次读取多个字节======");
//        byte[] buf = new byte[3];
//        int count = fileInputStream.read(buf);
//        System.out.println(count);
//        System.out.println(new String(buf));
//
//        int count2 = fileInputStream.read(buf);
//        System.out.println(count2);
//        System.out.println(new String(buf));
//
//        int count3 = fileInputStream.read(buf);
//        System.out.println(count3);
//        System.out.println(new String(buf,0,count3));

        // 使用循环解决
        byte[] bytes = new byte[3];
        int count  = 0;
        while((count = fileInputStream.read(bytes)) != -1){
            System.out.println(new String(bytes,0,count));
        }
        // 3. 关闭
        fileInputStream.close();
        System.out.println("执行完毕!!");
    }
}

3.2 FileOutputStream的使用

package javaOfIO;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;

/**
 * 演示文件字节输出流
 * FileOutputStream
 */
public class MyFileOutputStream {
    public static void main(String[] args) throws Exception {
        // 1. 创建文件字节输出流对象
        FileOutputStream fileOutputStream = new FileOutputStream("d:\\aaa.txt",true);// append为true表示 追加数据字符,不清空原有字符
        // 2. 写入文件
//        fileOutputStream.write(97);
//        fileOutputStream.write('b');
//        fileOutputStream.write('c');
        String string  = "helloworld\n";
        fileOutputStream.write(string.getBytes(StandardCharsets.UTF_8));
        // 3. 关闭
        fileOutputStream.close();
        System.out.println("执行完毕!!");
    }
}

3.3 字节流复制文件

package javaOfIO;

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

/**
 * 使用文件字节流实现文件的复制
 */
public class MyCopyFileWithStream {
    public static void main(String[] args) throws Exception{
        // 1. 创建流
        // 1.1 文件字节输入流
        FileInputStream fileInputStream = new FileInputStream("d:\\粉色背景.jpg");
        // 1.2 文件字节输出流
        FileOutputStream fileOutputStream = new FileOutputStream("d:\\003.jpg");
        // 2. 实现复制 一边读,一边写
        byte[] buf = new byte[1024];
        int count = 0 ; // 保存实际读取的字节个数
        while ((count = fileInputStream.read(buf)) != -1 ){
            fileOutputStream.write(buf,0,count);
        }
        // 3. 关比
        fileInputStream.close();
        fileOutputStream.close();
        System.out.println("执行玩匕");

    }
}

3.4 字符缓冲流

3.5 BufferedInputStream的使用

·缓冲流:BufferedInputStream/BufferedOutputStream
·提高I0效率,减少访问磁盘的次数;
·数据存储在缓冲区中,flush是将缓存区的内容写入文件中,也可以直接close。

package javaOfIO;

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

/***
 * 使用字节缓冲流读取文件
 *
 */
public class Demo04_BufferedInputStream {
    public static void main(String[] args) throws Exception{
        // 1. 创建BufferedInputStream
        FileInputStream fileInputStream = new FileInputStream("d:\\aaa.txt");
        BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
        // 2. 读取
//        int data =  0 ;
//        while ((data = bufferedInputStream.read()) != -1){
//            System.out.print((char) data);
//        }
        //  自己创建缓冲区
        byte[] buf = new byte[1024];
        int count= 0;
        while((count = fileInputStream.read(buf))!= -1 ){
            System.out.println(new String(buf,0, count));
        }
        // 3. 关闭
        bufferedInputStream.close();
    }
}

在这里插入图片描述

3.6 BufferedOutputStream的使用

实现缓冲的输出流。通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统。

缓冲区满了就flush

package javaOfIO;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;

/**
 * 使用字符缓冲流输出文件
 * BufferedOutputStream
 */
public class Demo05_BufferedOutputStream {
    public static void main(String[] args)  throws Exception{
        // 1. 创建字节输出缓冲流
        FileOutputStream fileOutputStream = new FileOutputStream("d:\\bbb.txt");
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
        // 2. 写入文件
        for (int i = 0; i < 10; i++) {
            bufferedOutputStream.write("helloworld\r\n".getBytes(StandardCharsets.UTF_8));  // 先写入8k缓冲区
            bufferedOutputStream.flush(); // 刷新到硬盘
        }

        // 3. 关闭(内部调用Flush方法)
        bufferedOutputStream.close();
    }
}

4. 对象流

在这里插入图片描述

4.1 序列化

java对象转其他对象(比如文件对象),就叫序列化,反过来就是反序列化。

package javaOfIO;

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

/**
 * 使用ObjectOutputStream 实现对象的序列化
 * 要求序列化的类 必须要实现implements Serializable 接口
 */
public class Demo06_ObjectOutputStream {
    public static void main(String[] args) throws Exception{
        // 1. 创建对象
        FileOutputStream fileOutputStream = new FileOutputStream("d:\\ccc.bin");  // bin表示二进制文件
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
        // 2. 序列化(写入操作)
        Student zhangsan= new Student("张三",20);
        objectOutputStream.writeObject(zhangsan);
        // 3. 关闭
        objectOutputStream.close();
        System.out.println("序列化完毕");

    }
}

package javaOfIO;

import java.io.Serializable;

public class Student implements Serializable {
    private static final long serialVersionUID = 3836721713802339996L; // 实现可以序列化的接口
    private String name;
    private int age;

    public Student() {
    }

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


4.2 反序列化

package javaOfIO;

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

/**
 * 使用ObjectOutputStream实现反序列化(读取重构对象)
 */
public class Demo07_ObjectInputStream {
    public static void main(String[] args) throws Exception{
        // 1. 创建对象流
        FileInputStream fileInputStream = new FileInputStream("d:\\ccc.bin");
        ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
        // 2. 读取文件(反序列化)
        Object s = (Student)objectInputStream.readObject();
        // 3. 关闭
        objectInputStream.close();
        System.out.println("玩匕");
        System.out.println(s.toString());
    }
}

4.3 序列化和反序列化注意事项

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

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

/**
 * 使用ObjectOutputStream 实现对象的序列化
 * 要求序列化的类 必须要实现implements Serializable 接口
 */
public class Demo06_ObjectOutputStream {
    public static void main(String[] args) throws Exception{
        // 1. 创建对象
        FileOutputStream fileOutputStream = new FileOutputStream("d:\\ccc.bin");  // bin表示二进制文件
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
        // 2. 序列化(写入操作)
        Student zhangsan= new Student("张三",20);
        Student lisi= new Student("李四",20);

        ArrayList<Student> list = new ArrayList<>();
        list.add(zhangsan);
        list.add(lisi);
        objectOutputStream.writeObject(list);
        // 3. 关闭
        objectOutputStream.close();
        System.out.println("序列化完毕");

    }
}

package javaOfIO;

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;

/**
 * 使用ObjectOutputStream实现反序列化(读取重构对象)
 */
public class Demo07_ObjectInputStream {
    public static void main(String[] args) throws Exception{
        // 1. 创建对象流
        FileInputStream fileInputStream = new FileInputStream("d:\\ccc.bin");
        ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
        // 2. 读取文件(反序列化)
//        Object s = (Student)objectInputStream.readObject();
//        Object s2 = (Student)objectInputStream.readObject();
        ArrayList<Student> list = (ArrayList<Student>) objectInputStream.readObject();
        // 3. 关闭
        objectInputStream.close();
        System.out.println("玩匕");
//        System.out.println(s.toString());
        System.out.println(list.toString());
    }
}

5 字符流

5.1 常见字符编码

在这里插入图片描述
当编码方式和解码方式不一致时,会出现乱码。

5.2 字符流抽象类

在这里插入图片描述

5.3 FileReader的使用

· FileReader:
·public int readKchar[]c)从流中读取多个字符,将读到内容存入
c数组,返回实际读到的字符数;如果达到文件的尾部,则返回-1。
· FileWriter:
·public void write(String str)一次写多个字符,将b数组中所有字符,写入输出
流。

package javaOfIO;

import java.io.FileReader;

/**
 * 使用FileReader读取文件
 */
public class Demo202_FieReader {
    public static void main(String[] args) throws Exception{
        // 1. 创建FileReader 文件字符输入流
        FileReader fileReader = new FileReader("d:\\hello.txt");
        // 2. 读取
        // 2.1 单个读取
//        int data = 0;
//        while ((data = fileReader.read()) != -1){
//            System.out.print((char)data);
//        }
        // 2.2 字符缓冲区
        int count  = 0;
        char[] chars = new char[1024];
        while ((count = fileReader.read(chars)) != -1){
            System.out.print(new String(chars,0,count));
        }

        // 3. 关闭
        fileReader.close();
    }

}

5.4 FileWriter的使用

package javaOfIO;

import java.io.FileWriter;

public class Demo203_FileWriter {
    public static void main(String[] args) throws Exception{
        // 1. 创建FileWriter对象
        FileWriter fileWriter = new FileWriter("d:\\write.txt");
        // 2. 写入
        for (int i = 0; i < 10; i++) {
            fileWriter.write("java是世界上最好的语言!\n");
            fileWriter.flush();
        }
        // 3. 关闭
        fileWriter.close();
        System.out.println("wanbi ");
    }
}

5.5 字符流复制文件

只能复制文本文件,不能复制图片或二进制文件

使用字节流复制任意文件

package javaOfIO;

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

public class Demo204 {
    public static void main(String[] args) throws Exception{
        // 1. increte
        FileReader fileReader = new FileReader("d:\\write.txt");
        FileWriter fileWriter = new FileWriter("d:\\write2.txt");
        // 2. read and writer
        int data = 0;
        while ((data = fileReader.read())!=-1){
            fileWriter.write(data);
            fileWriter.flush();
        }
        // 3. close
        fileReader.close();
        fileWriter.close();
    }
}

5.6 BufferedReader的使用

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

package javaOfIO;

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

/**
 * 使用字符缓冲流读取文件
 * bufferedReader
 */
public class Demo205_BufferedReader {
    public static void main(String[] args) throws Exception{
        // 创建缓冲流
        FileReader fileReader = new FileReader("d:\\write.txt");
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        // reader
        //2.1
//        char[] chars = new char[1024];
//        int count = 0;
//        while((count = bufferedReader.read(chars)) != -1){
//            System.out.println(new String(chars,0,count));
//        }
        //2.2  一行一行度
        String line = null;
        while ((line = bufferedReader.readLine())!=null){
            System.out.println(line);
        }
        // 3. 关闭
        bufferedReader.close();
    }
}

5.7 BufferedWriter的使用

package javaOfIO;

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

public class Demo205_BufferedWriter {
    public static void main(String[] args) throws Exception{
        // 1. 创建bufferedWriter对象
        FileWriter fileWriter = new FileWriter("D:\\buffer.txt");
        BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
        // 2. 写入
        for (int i = 0; i < 10; i++) {
            bufferedWriter.write("好好学习,天天向上\n");
            bufferedWriter.newLine(); // 换行
            bufferedWriter.flush();
        }
        bufferedWriter.close();
        System.out.println("wanbu");
    }
}

6. 打印流

6.1 PrintWriter

·PrintWriter:
·封装了print()/println()方法,支持写入后换行。
·支持数据原样打印

package javaOfIO;

import java.io.PrintWriter;

/**
 * 演示printwriter的使用
 */
public class Demo206207 {
    public static void main(String[] args) throws Exception{
        // 1. 创建打印流
        PrintWriter printWriter = new PrintWriter("d:\\print.txt");
        // 2. print
        printWriter.println(97);
        printWriter.println(true);
        printWriter.println(3.14);
        printWriter.println("a");
        // 3. close
        printWriter.close();
    }
}

7. 转换流

·桥转换流:InputStreamReader/OutputStreamWriter
·可将字节流转换为字符流。
·可设置字符的编码方式。

7.1 InputStreamReader的使用

package javaOfIO;

import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.security.spec.RSAOtherPrimeInfo;

/**
 * Demo301_InputStreamReader 读取文件, 指定使用的编码
 *
 */
public class Demo301_InputStreamReader {
    public static void main(String[] args) throws Exception{
        // 1. 创建 InputStreamReader 对象
        FileInputStream fileInputStream = new FileInputStream("d:\\write.txt");
        InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "utf-8");
        // read file
        int data = 0;
        while((data = inputStreamReader.read()) != -1){
            System.out.print((char) data);
        }
        // 3. 关闭
        inputStreamReader.close();

    }
}

package javaOfIO;

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

public class Demo302_OutputStreamReader {
    public static void main(String[] args) throws  Exception{
        FileOutputStream fileOutputStream = new FileOutputStream("d:\\info.txt");
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, "gbk");

        // 2
        for (int i = 0; i < 10; i++) {
            outputStreamWriter.write("我爱北京\t\n");
            outputStreamWriter.flush();
        }
        // 3
        outputStreamWriter.close();
        System.out.println("good");
    }

}

8. file类

在这里插入图片描述

8.1 File类文件操作

package javaOfIO;

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

/**
 * 1. 分隔符
 * 2. 文件操作
 * 3. 文件夹操作
 */
public class DomeFile01 {
    public static void main(String[] args) throws Exception{
       // separator();
        fileOpe();
    }
    //  1. 分隔符
    public static void separator(){
        System.out.println("路径分隔符:" + File.pathSeparator);
        System.out.println("名称分隔符:" + File.separatorChar);
    }
//    路径分隔符:;
//    名称分隔符:\
    // 2. 文件操作
    public static void fileOpe() throws Exception {
        // 1. 创建文件
        File file = new File("d:\\file.txt");
//        File file = new File("file.txt"); // 默认在项目上进行创建
        //System.out.println(file.toString());

        if(!file.exists()){
            boolean newFile = file.createNewFile();// 返回值为bool类型
            System.out.println("创建结果:" + newFile);

        }
        // 2. 删除文件
        // 2.1 直接删除
        // System.out.println("delete end:"+file.delete());
        // 2.2 使用jvm退出时 删除
//        file.deleteOnExit();
//        Thread.sleep(5000);
        // 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("获取文件的创建时间:"+ new Date(file.lastModified()).toLocaleString());
        // 4 判断

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

8.2 File类文件夹操作

package javaOfIO;
/**
 * 1. 分隔符
 * 2. 文件操作
 * 3. 文件夹操作
 */
import java.io.File;
import java.util.Date;

public class DomeFile02 {

    public static void main(String[] args) throws Exception{
        // separator();
        directorOpe();
    }
    //  1. 分隔符
    public static void separator(){
        System.out.println("路径分隔符:" + File.pathSeparator);
        System.out.println("名称分隔符:" + File.separatorChar);
    }
    //    路径分隔符:;
//    名称分隔符:\
    // 2. 文件夹操作
    public static void directorOpe() throws Exception {
        // 1. 创建文件夹
        File dir = new File("d:\\aaa\\bbb\\ccc");
        System.out.println(dir.toString());

        if(!dir.exists()){
//            boolean newdir= dir.mkdir();// 只能创建单级目录
            boolean newdir = dir.mkdirs();// 能创建多级目录
            System.out.println("创建结果:" + newdir );

        }
        // 2. 删除文件夹
        // 2.1 直接删除(空目录)
//         System.out.println("delete end:"+dir.delete()); // 只能删掉单目录,空目录
        // 2.2 使用jvm退出时 删除
        dir.deleteOnExit();
        Thread.sleep(5000);
        // 3. 获取文件夹信息
        System.out.println("获取文件夹的绝对路径:"+ dir.getAbsolutePath());
        System.out.println("获取文件夹的路径:"+ dir.getPath());
        System.out.println("获取文件夹的名称:"+ dir.getName());
        System.out.println("获取文件夹的父目录:"+ dir.getParent());
        System.out.println("获取文件夹的创建时间:"+ new Date(dir.lastModified()).toLocaleString());
        // 4 判断
        System.out.println("是否是文件Jia:" + dir.isDirectory());
        System.out.println("是否隐藏:" + dir.isHidden());

        // 5. 遍历文件夹信息
        File dir2 = new File("d:\\证件照");
        String[] files = dir2.list();
        for (String file : files) {
            System.out.println(file);
        }
    }
}

9. 文件过滤器FileFilter接口

public interface FileFilter
	 boolean accept(File pathname)

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

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

10.递归遍历和递归删除

package javaOfIO;

import java.io.File;

/**
 * 递归遍历文件夹
 * 案例2:递归删除文件夹
 */
public class ListDemo {
    public static void main(String[] args) {
        listDir(new File("d:\\新建文件夹"));
        deleteDir(new File("d:\\新建文件夹"));

    }
    // 案例1:递归遍历文件夹
    public static void listDir(File dir){
        File[] files = dir.listFiles();
        System.out.println(dir.getAbsolutePath());
        if(files!=null && files.length>0){
            for (File file : files) {
                if(file.isDirectory()){
                    listDir(file); // 递归
                }else{
                    System.out.println(file.getAbsolutePath());
                }
            }
        }

    }

    // 案例2:递归删除文件夹
    public static void deleteDir(File dir){
        File[] files = dir.listFiles();
        if(files!=null && files.length>0){
            for (File file : files) {
                if(file.isDirectory()){
                    deleteDir(file);
                }else{
                    System.out.println(file.getAbsolutePath() + "  删除:" + file.delete());
                }
            }
        }
        System.out.println(dir.getAbsolutePath() + "  删除:" + dir.delete());
    }
}

11.Properties

·Properties:属性集合,继承hashtable,线程安全的集合
・特点
·1存储属性名和属性值
·2属性名和属性值都是字符串类型
·3没有泛型
·4 和流有关

package javaOfIO;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.Properties;
import java.util.Set;

/**
 * Properties集合使用
 */
public class Demo_Properties {
    public static void main(String[] args) throws  Exception{
        // 1
        Properties properties = new Properties();
        // 2. add
        properties.setProperty("username", "张三");
        properties.setProperty("age","20");
        // 2. 遍历
        // 3.1 keyset
        // 3.2 entrySet
        // 3.3 StringPropertyNames()
        Set<String> strings = properties.stringPropertyNames(); // 获取属性名
        for (String string : strings) {
            System.out.println(string + ":" + properties.getProperty(string));
        }
        // 4. 和流有关的方法
        // -------------------------list方法-----------------------
//        PrintWriter printWriter = new PrintWriter("d:\\print.txt");
//        properties.list(printWriter);
//        printWriter.close();
        // -------------------------stroe方法保存-----------------------
//        FileOutputStream fileOutputStream = new FileOutputStream("d:\\store.properties");
//        properties.store(fileOutputStream, "注释");
//        fileOutputStream.close();
        // -------------------------load方法加载-----------------------
        Properties properties1 = new Properties();
        FileInputStream fileInputStream = new FileInputStream("d:\\store.properties");
        properties1.load(fileInputStream);
        fileInputStream.close();
        System.out.println(properties1.toString());

    }
}

总结

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值