Java IO流专题笔记

Java IO流专题笔记

2022-4-19笔记

在这里插入图片描述

在这里插入图片描述

文件

文件在程序中是以流形式来操作的

在这里插入图片描述

    • 数据在数据源(文件)和程序(内存)之间经历的路径
  • 输入流
    • 数据从数据源(文件)到程序(内存)的路径
  • 输出流
    • 数据从程序(内存)到数据源(文件)的路径

常用文件操作

创建文件对象相关构造器方法
  • new File(String pathname);//根据路径创建一个File对象
    new File(File parent,String child);//根据父类目录文件+子路径构建
    new File(String parent,String child);//根据父类目录+子路径构造
    
  • @Test
    public void create01() throws IOException {
        String filePath = "d:\\new.txt";
        File file = new File(filePath);
    
        file.createNewFile();
    }
    
获取文件的相关信息
  • getName()

  • getAbsoultePath()

  • getParent()

  • length()

  • exsits()

  • isFile()

  • isDirectory()

    • @Test
      public void info(){
          File file = new File("F:\\毕业设计\\论文\\参考文献.txt");
          System.out.println("文件名="+file.getName());
          System.out.println("绝对路径="+file.getAbsolutePath());
          System.out.println("文件父级目录="+file.getParent());
          System.out.println("文件大小(字节)="+file.length());
          System.out.println("是否存在="+file.exists()); 
          System.out.println("是否一个文件="+file.isFile());
          System.out.println("是否一个目录="+file.isDirectory());
      }
      
  • mkdir() 创建一级目录

  • mkdirs() 创建多级目录

  • delete() 删除空目录或文件

IO流原理及流的分类

Java IO流原理

  • I/O是input/Output的缩写,I/O技术是非常实用的技术,用于处理数据传输,如 读写文件,网络通讯
  • Java程序中,对于数据的输入/输出操作以“流(Stream)”的方式进行
  • Java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过方法输入或输出数据
  • 输入input:
    • 读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中
  • 输出output:
    • 将程序(内存)数据输出到磁盘、光盘等存储设备中
流的分类

按操作数据单位不同分类:字节流(8bit)、字符流(按字符)

按数据流的流向不同:输入流、输出流

按流的角色不同分为:节点流、处理流/包装流

抽象基类字节流字符流
输入流InputStreamReader
输出流OutputStreamWriter

IO流体系图-常用类

字节流

InputStream常用子类

在这里插入图片描述

  • FileInputStream 文件输入流

    • //单个字节读取 效率较低 -> 使用read(byte [])优化
      @Test
      public void readFile01(){
          String filePath="F:\\毕业设计\\论文\\参考文献\\参考文献.txt";
          int readData=0;
          FileInputStream fileInputStream = null;
          try {
              fileInputStream = new FileInputStream(filePath);
              //返回-1 说明文件读取完毕
              while((readData = fileInputStream.read())!=-1){
                  //如果有文字不推荐使用 字符流 会乱码
                  System.out.print((char)readData);
              }
          } catch (IOException e) {
              e.printStackTrace();
          }finally {
              //关闭文件流,释放资源
              try {
                  fileInputStream.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
      
          }
      }
      
      @Test
      public void readFile02(){
          String filePath="F:\\毕业设计\\论文\\参考文献\\参考文献.txt";
          byte[] buf = new byte[8];//一次读8个字节
          int bufLen=0;
          FileInputStream fileInputStream = null;
          try {
              fileInputStream = new FileInputStream(filePath);
              //返回-1 说明文件读取完毕
              //如果读取正常,返回实际读取的字节数 最大9个
              while((bufLen = fileInputStream.read(buf))!=-1){
                  //如果有文字不推荐使用 字符流 会乱码
                  System.out.print(new String(buf,0,bufLen));
              }
          } catch (IOException e) {
              e.printStackTrace();
          }finally {
              //关闭文件流,释放资源
              try {
                  fileInputStream.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
      
          }
      }
      
  • BufferInputStream 缓冲字节输入流

  • ObjectInputStream 对象字节输入流

OutputStream常用子类
  • FileOutputStream 文件输出流

    • // 演示将数据写入到文件中,如果该文件不存在,则创建该文件
      @Test
      public void writeFile(){
          String filePath="F:\\毕业设计\\论文\\参考文献.txt";
          FileOutputStream fileOutputStream=null;
      
          try {
              // new FileOutputStream(filePath); 该方式是覆盖添加
              // new FileOutputStream(filePath,true); 该方式是在文件后方append添加
              fileOutputStream = new FileOutputStream(filePath);
              // 1.写入一个字节
              fileOutputStream.write('H');
              // 2.写入多个字符
              String str = "hello world";
              fileOutputStream.write(str.getBytes());
              // 3.指定字符长度写入
              fileOutputStream.write(str.getBytes(),0,2);
          } catch (IOException e) {
              e.printStackTrace();
          } finally {
          }
      }
      
文件拷贝

思路分析

  • 先创建文件输入流,将文件读入到程序
  • 再创建文件输出流,将读取到的文件数据,写入到指定的文件

代码演示

@Test
public void fileCopy(){
    String oldFilePath = "F:\\毕业设计\\论文\\图\\借阅信息主动推送.png";
    String newFilePath = "F:\\毕业设计\\论文\\借阅信息主动推送.png";
    FileInputStream fileInputStream = null;
    FileOutputStream fileOutputStream = null;
    byte[] bytes = new byte[8];
    int len=0;
    try {
        fileInputStream = new FileInputStream(oldFilePath);
        fileOutputStream = new FileOutputStream(newFilePath);
        while((len = fileInputStream.read(bytes))!=-1){
            fileOutputStream.write(bytes);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            fileInputStream.close();
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

字符流

FileReader和FileWriter介绍

FileReader和FileWriter是字符流,按照字符来操作io

FileReader相关方法
  • new FileReader(File/String);
    
    read();//每次读取单个字符,返回字符,如果文件末尾返回-1
    
    reader(char[]); //批量读取多个字符数组,返回读到的字符数,如果文件末尾返回-1
    //相关API
    new String(char[]); //将char[]转换成String
    new String(char[],off,len);//将char[]的指定内容换砖成String'
    
  • //读取文件 
    @Test
    public void fileReader(){
        String filePath="F:\\毕业设计\\论文\\参考文献\\参考文献.txt";
        FileReader fileReader = null;
        int readerData=0;
        try {
            fileReader = new FileReader(filePath);
            while((readerData = fileReader.read()) != -1){
                System.out.print((char)readerData);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
FileWriter常用方法
  • new FileWriter(File/String); //覆盖模式,相当于流的指针首段
    
    new FileWriter(File/String,true); //追加模式,相当于流的指针再尾端
    
    write(int); //写入单个地府
    
    write(char[]); //写入指定数组
    
    write(char[],off,len); //写入指定数组的指定部分
    
    write(String); //写入整个字符串
    
    write(String,off,len); //写入字符串的指定部分
    
    //相关API
    String.toCharArray(); //将String转换成char[]
    //注意
    //FileWriter使用后,必须要关闭(close) 或 刷新(flush),否则写入不到指定的文件
        
    

节点流和处理流

在这里插入图片描述

基本介绍

  • 节点流
    • 可以从一个特点的数据源读写数据,如FileReader、FileWriter,根据不同的文件程序,选择不同的分类
    • 在这里插入图片描述
  • 在这里插入图片描述
  • 处理流
    • 也称包装流,是“连接”已存在的流(节点流或处理流)之上,为程序提供更强大的读写功能,也更加灵活 ,如BufferedReader、BufferedWriter
    • 在这里插入图片描述
  • 在这里插入图片描述
节点流和处理流的区别和联系

区别

  1. 节点流是底层流/低级流,直接跟数据源相接
  2. 处理流包装节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入和输出
  3. 处理流(包装流)对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相联

处理流的功能主要体现方面

  1. 性能的提高:主要以增加缓冲的方式来提高输入输出效率
  2. 操作的便捷:处理流可能提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便
处理流BufferedReader 和 BufferedWriter
  • BufferedRead 和 BufferedWriter 属于字符流,是按照字符来读取数据的

  • 关闭处理流,只需要关闭外层流即可

    • 例如关闭BufferedReader时,会自动关闭其底层的节点流的关闭
  • BufferedReader应用案例

    • package main.java.com.chapter19.reader;
          
      import java.io.BufferedReader;
      import java.io.FileNotFoundException;
      import java.io.FileReader;
          
      /**
       * @Author BaoYuan
       * @CreateDate 2022/4/21 15:44
       * @Version 1.0
       */
      public class BufferedReader_ {
          public static void main(String[] args) throws Exception {
              String filePath="F:\\毕业设计\\论文\\参考文献.txt";
              BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
              String line="";
          
              while((line = bufferedReader.readLine())!=null){
                  //  当读取完成时 返回null
                  System.out.print(line);
              }
              bufferedReader.close();
          }
      }
      
  • BufferedWriter案例

    • package main.java.com.chapter19.write;
          
      import java.io.BufferedWriter;
      import java.io.FileWriter;
          
      /**
       * @Author BaoYuan
       * @CreateDate 2022/4/21 15:50
       * @Version 1.0
       */
      public class BufferedWriter_ {
          public static void main(String[] args) throws Exception {
              String filePath="F:\\毕业设计\\论文\\参考文献.txt";
              BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath));
              String s = "hello World!";
              //  默认覆盖源文件内容
              bufferedWriter.write(s);
              //   换行
              bufferedWriter.newLine();
              bufferedWriter.write(s);
              bufferedWriter.newLine();
              bufferedWriter.write(s);
              bufferedWriter.close();
          }
      }
      
  • Bufferd文件拷贝

    • package main.java.com.chapter19.FileCopy;
              
      import java.io.BufferedReader;
      import java.io.BufferedWriter;
      import java.io.FileReader;
      import java.io.FileWriter;
              
      /**
       * @Author BaoYuan
       * @CreateDate 2022/4/21 15:56
       * @Version 1.0
       */
      public class BufferCopy_ {
          public static void main(String[] args) throws Exception {
              // 不要去操作二进制文件(视频、音频、pdf、word),可能会造成文件损坏
              String oldFilePath="F:\\毕业设计\\论文\\参考文献.txt";
              String newFilePath="F:\\毕业设计\\论文\\参考文献Copy.txt";
              BufferedReader bufferedReader = new BufferedReader(new FileReader(oldFilePath));
              BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(newFilePath));
              String s="";
              while((s = bufferedReader.readLine())!=null){
                  bufferedWriter.write(s);
                  bufferedWriter.newLine();
              }
              bufferedReader.close();
              bufferedWriter.close();
              
          }
      }
      
处理流 BufferedInputStream 和 BufferedOutputSteam
  • BufferedInputStream 是字节流,在创建BufferedInputStream时,会创建一个内部缓冲区数据
  • BufferedOutputStream时字节流,实现换成的输出流,可以将多个字节写入底层输出流中,而不必对每次字节写入调用底层系统

图片拷贝

package main.java.com.chapter19.FileCopy;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

/**
 * @Author BaoYuan
 * @CreateDate 2022/4/21 19:13
 * @Version 1.0
 */
public class BufferedStreamCopy {
    public static void main(String[] args) throws Exception {
        String oldFilePath="F:\\毕业设计\\论文\\借阅信息主动推送.png";
        String newFilePath="F:\\毕业设计\\论文\\借阅信息主动推送2.png";
        byte[] ch =  new byte[8];
        int res = 0;
        BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(oldFilePath));
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(newFilePath));
        while((bufferedInputStream.read(ch)) != -1){
                bufferedOutputStream.write(ch);
        }
        bufferedInputStream.close();
        bufferedOutputStream.close();
    }
}
对象流 ObjectInputStream 和 ObjectOutputStream(序列化、反序列化)
  • 序列化就是在保存数据时,保存数据得值和数据类型
  • 反序列化就是在恢复数据时,恢复数据得值和数据类型
  • 需要让某个对象支持序列化机制,则必须要让其类可序列化,为了让某个类可序列化的,该类必须实现如下两个接口之一
    • Serializable -> 这是一个标记接口,没有方法,推荐使用这个
    • Externalizable ->该接口有方法需要实现

序列化实现

package main.java.com.chapter19.outputStream_;

import main.java.com.test.E;

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

/**
 * @Author BaoYuan
 * @CreateDate 2022/4/21 21:13
 * @Version 1.0
 */
public class ObjectOutputStream_ {
    public static void main(String[] args) throws Exception {
        //序列化后保存文件格式并非自己设计
        String filePath = "F:\\毕业设计\\论文\\data.text";
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));

        oos.write(100);
        oos.writeUTF("啊啊啊");
        oos.writeBoolean(true);
        oos.writeObject(new Dog("旺财",2));
        oos.close();
    }
}

class Dog implements Serializable{
    private String name;
    private int age;

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

反序列化实现

package main.java.com.chapter19.InputStream;

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

/**
 * @Author BaoYuan
 * @CreateDate 2022/4/21 21:37
 * @Version 1.0
 */
public class ObjectInputStream_ {
    public static void main(String[] args) throws Exception {
        String filePath = "F:\\毕业设计\\论文\\data.text";
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));

        //读取的顺序 必须与写入时一样 否则抛出异常
        System.out.println(ois.readInt());
        System.out.println(ois.readUTF());
        System.out.println(ois.readBoolean());
        System.out.println(ois.readObject());

        ois.close();

    }
}
注意事项
  • 读写顺序需一致

  • 要求实现序列化或反序列化对象,需要实现Serializable

  • 序列化的类中建议添加SeriaVersionUID,为提高版本的兼容性

    • // 序列化的版本号,可以提高兼容性
      private static final long seriaVersionUID = 1L;
      
  • 序列化对象时,默认将里面所有属性都进行序列化,但除了static或transient修饰的成员

  • 序列化对象时,要求里面的属性的类型也需要实现序列化接口

  • 序列化具备可继承性,也就是如果某类已经实现了序列化,则它的所有子类也已经默认实现了序列化

标准输入输出流
  • System.in 标准输入 InputStream 键盘
    • 编译类型:InputStream
    • 运行类型:BufferedInputStream
  • System.out 标准输出 PrintStream 显示器
    • 编译类型:PrintStream
    • 运行类型:PrintStream
转换流 InputStreamReader 和 OutputStreamWriter

介绍

  • InputStreamReader:Reader的子类,可以将InputStream(字节流)包装成Reader(字符流)

    • package main.java.com.chapter19.reader;
        
      import java.io.*;
        
      /**
       * @Author BaoYuan
       * @CreateDate 2022/4/22 15:20
       * @Version 1.0
       */
      public class InputStreamReader_ {
          public static void main(String[] args) throws IOException {
              String newFilePath="F:\\毕业设计\\论文\\参考文献Copy.txt";
              InputStreamReader isr = new InputStreamReader(new FileInputStream(newFilePath), "utf-8");
              BufferedReader bufferedReader = new BufferedReader(isr);
              String line = "";
              while((line = bufferedReader.readLine()) != null){
                  System.out.println(line);
              }
        
              bufferedReader.close();
          }
      }
      
    • 在这里插入图片描述

  • OutputStreamWriter:Writer的子类,实现OutputStream(字节流)包装成Writer(字符流)

    • package main.java.com.chapter19.write;
        
      import java.io.FileOutputStream;
      import java.io.IOException;
      import java.io.OutputStreamWriter;
        
      /**
       * @Author BaoYuan
       * @CreateDate 2022/4/22 15:26
       * @Version 1.0
       */
      public class OutputStreamReader_ {
          public static void main(String[] args) throws IOException {
              String newFilePath="F:\\毕业设计\\论文\\Copy.txt";
              OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(newFilePath),"utf-8");
              osw.write("hello world!!!");
              osw.close();
          }
      }
      
    • 在这里插入图片描述

  • 当处理纯文本数据时,如果使用字符流效率高,并且可以有效解决中文问题,所以建议将字节流转换成字符流

  • 可以在使用时指定编码格式(比如utf-8、gbk、gb2312、ISO8859-1等)

打印流 PrintStream 和 PrintWriter

只有输出流没有输入流

在这里插入图片描述

在这里插入图片描述

Properties类

常见方法

  • load():加载配置文件的键值对搭配到Properties对象
  • list():将数据显示到指定设备/流对象
  • getProperty(key):根据键值获取值
  • setProperty(key,value):设置键值对到Properties对象
  • store():将properties中键值对存储到配置文件,在idea中,保存信息到配置文件,如果含有中文,会存储为unicode码
  • http://tool.chinaz.com/tools/unicode.aspx unicode码查询工具
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值