小王Java学习打卡day14——IO流

本文介绍了Java中的IO流概念,包括输入输出、File类、四大基本流、缓冲流和字符编码。讲解了如何使用File类操作文件路径,通过实例展示了文件流的使用,如读写文件、文件拷贝。还涵盖了缓冲区的重要性以及如何使用缓冲流提高性能。此外,文章还提及了字符编码的历史发展和常用编码集,以及序列化和打印流的基本概念。
摘要由CSDN通过智能技术生成

IO 的概述

  1. 概述:数据存到内存里面,程序运行结束之后,数据就没了,此时就需要把数据持久化存储起来
  2. input 输入(读)
  3. output输出(写)
  4. java.io 包中

File 类

  1. file类:文件目录的抽象

  2. 文件路径的分隔符:

    • windows:使用 \ 来进行路径分割,在java中使用 \\ 来分割, ; 来分割属性
    • unix: / 分割路径, : 分割属性(要区分大小写)
    • windows 不区分大小写
  3. 获取当前系统的分隔符:

    • 分割属性的获取
    //获取分割属性
    String s = File.pathSeparator;
    System.out.println(s);
    char pathSeparatorChar = File.pathSeparatorChar;
    System.out.println(pathSeparatorChar);
    //获取斜线的分隔符
    String separator = File.separator;
    System.out.println(separator);
    
  4. 获取路径和名称

    • 相对路径

    • 绝对路径:从根目录直接能进入的路径

      //获取绝对路径
      public String getAbsolutePath() {
          return fs.resolve(this);
      }
      //获取绝对路径的文件
      public File getAbsoluteFile() {}
      //获取路径
      public String getPath() {}
      //获取上级目录
      public String getParent() {}
      
      //获取文件名称
      public String getName() {}
      
      1. 如何创建一个文件,以及基本方法

        • ​ 构造器
        //直接使用路径创建文件
        public File(String pathname) {}
        //根据绝对路径创建文件
        File file = new File("D:\\software\\hello.txt");
        //先创建目录对象,然后再创建文件
        File file1 = new File("D:\\software");
        File file2 = new File(file1, "hello.txt");
        //目录和文件分成两个参数传
        File file3 = new File("D:\\software", "hello.text");
        
  • ​ 方法的学习
//判断是不是文件
public boolean isFile() {}
//判断是不是目录
 public boolean isDirectory() {}
//删除文件
  public boolean delete() {}
//判断文件或目录是否存在
   public boolean exists() {}
//创建目录(存在就不创建)
 public boolean mkdir() {}
//查看当前目录所有的文件
  public String[] list() {}
//列出所有的文件对象
public File[] listFiles() {
//在目录里创建新的文件
File file4 = new File("D:\\software\\我爱祖国.mp3");
boolean newFile = file4.createNewFile();
//重命名
public boolean renameTo(File dest) {}
  1. 需求:列出指定目录中的所有文件,包括子文件夹中的所有文件及其子文件。递归

    • 回顾递归(5的阶乘)
    public static void main(String[] args) {
        //5的阶乘
        int i = recursion(5);
        System.out.println(i);
    }
    public static int recursion(int a) {
        if (a == 1) {
            return 1;
        } else {
            return a * recursion(a - 1);
        }
    }
    

需求:列出指定目录中的所有文件,包括子文件夹中的所有文件及其子文件。递归

public static void main(String[] args) {
    File file = new File("C:\\Users\\wxj\\Desktop\\Study change life\\day13");
   fileRecursion(file);

}

public static void fileRecursion(File file){
    //第一层级
    File[] files = file.listFiles();
    System.out.println(file.getAbsolutePath());
    for (File f : files) {
        if (f.isFile()){
            System.out.println("  -"+f.getName());
        }else {
            fileRecursion(f);
        }
    }

需求:批量修改文件名

public static void main(String[] args) {
    File file = new File("C:\\Users\\wxj\\Desktop\\Study change life\\day13\\day13_work");
    File[] files = file.listFiles();
    //需要修改的文件名字符串
    String deleteName = "呃呃呃饿";
    for (File f : files) {
        //删选包含字符串的文件
        if (f.getName().contains(deleteName)){
            //使用replace进行更改名字
            String replace = f.getName().replace(deleteName, "");
            File renameFile = new File(file, replace);
            f.renameTo(renameFile);
        }
    }
}

需求:打印指定目录下面 .java 结尾的资源

  • 文件过滤器

    FilenameFilter filenameFilter = new FilenameFilter() {
        //匿名内部类
        @Override
        public boolean accept(File dir, String name) {
            return false;
        }
    };
    
  • 需求实现

public static void main(String[] args) {
    File file = new File("D:\\java\\29");
    File[] files = file.listFiles(new FilenameFilter() {
        @Override
        public boolean accept(File dir, String name) {
            return new File(file,name).isFile() && name.endsWith(".java");
        }
    });
    for (File f : files) {
        System.out.println(f.getName());
    }
}

IO流

  1. I O 设备

    • 输入:键盘,鼠标,麦克风
    • 输出:显示器,打印机,音响
  2. 程序

    • 输入:从磁盘到内存里
    • 输出:从内存写数据到磁盘文件里
  3. IO 流的分类

  • 按流向(输入输出流)
  • 按数据单位(字符字节流)
  • 四大基本流:
    • 字节输出流
    • 字节输入流
    • 字符输出流
    • 字符输入流
  • 注意:不管是什么流,最后都需要关闭资源。close,如果不关闭,磁盘文件一直被占用,不能够删除和修改。**

文件流

  1. 字节流

    • FileOutputStream 文件输出流

      • 需求:读 C:\Users\wxj\Desktop\Study change life\day14\task02\任务作业.txt 文件,并且写入 wangxiaoj进去

        File file = new File("C:\\Users\\wxj\\Desktop\\Study change life\\day14\\task02\\任务作业.txt");
        FileOutputStream stream = new FileOutputStream(file,true);
        stream.write("wangxiaoj".getBytes());
        stream.close();
        
      • 需求:C:\Users\wxj\Desktop\Study change life\day14\task02\任务作业.txt 读出来,在程序中打印

        File file = new File("C:\\Users\\wxj\\Desktop\\Study change life\\day14\\task02\\任务作业.txt");
        //创建输入流
        FileInputStream inputStream = new FileInputStream(file);
        //创建数组,设置每次最大读取空间
        byte[] bytes = new byte[1024];
        System.out.println(Arrays.toString(bytes));
        int length = -1;
        //循环读,读一次只能读一个
        while ((length = inputStream.read(bytes) )!= -1){
            String str = new String(bytes, 0, length);
            System.out.println(str);
        }
         inputStream.close();
        
        • 使用字节流实现文件的拷贝

          public static void main(String[] args) throws IOException {
              //源文件
              File srcFile = new File("C:\\Users\\wxj\\Desktop\\Study change life\\day14\\task02\\任务作业.txt");
              //目标文件
              File deskFile = new File("C:\\Users\\wxj\\Desktop\\Study change life\\day14\\task02\\拷贝目标文件.txt");
              //源文件 输入流
              FileInputStream srcInputStream = new FileInputStream(srcFile);
              //目标文件输出流
              FileOutputStream deskOutputStream = new FileOutputStream(deskFile);
          
              byte[] buffer = new byte[10];
              int length= -1;// 表示读了多少个字节,  -1 表示还没有读完
              //不等于 -1 表示还没有读完,就一直读下去
              while ((length=srcInputStream.read(buffer))!=-1){
                  //把读到的写到目标文件里面
                  System.out.println(Arrays.toString(buffer));
                  deskOutputStream.write(buffer);
              }
              //关闭资源
              srcInputStream.close();
              deskOutputStream.close();
          }
          
  2. 字符流

    • FileReader (字符输入流)
public static void main(String[] args) throws IOException {
    File file = new File("C:\\Users\\wxj\\Desktop\\Study change life\\day14\\task02\\任务作业.txt");
    FileReader fileReader = new FileReader(file);
    char[] chars = new char[12];
    int length = -1;
    while ((length = fileReader.read(chars))!= -1){
        String s = String.valueOf(chars);
        System.out.println(s);
    }
    fileReader.close();
  • FileWrite (字符输出流)
    public static void main(String[] args) throws IOException {
        File file = new File("C:\\Users\\wxj\\Desktop\\Study change life\\day14\\task02\\任务作业.txt");
        FileWriter fileWriter = new FileWriter(file,true);//没有加true则会覆盖之前的数据
        fileWriter.write("这是新写进来的数据:376783487<br>");
        fileWriter.close();
    }
  1. 字节流和字符流的选择
  • 二进制文件,图片,视频,音频,必须使用字节流
  • 文本文件可以使用字符流
  • 不清楚就全部使用字节流
  1. fiush 刷新操作

    • 计算机直接访问外部的磁盘文件,比直接操作内存会慢很多,可以设置一个缓冲区,写的时候先写到内存里面,达一个设定值才写到磁盘,减少与与磁盘的交互。
    • 使用缓冲区的意义:
      • 提高cpu的使用率
      • 回滚写入的数据
    • 操作系统使用 -1 来表示磁盘文件 结尾的标志
    • io 是最影响程序性能的。缓冲区一般设置使用容量的整数倍,可以提高io性能
  2. try()… catch() 资源自动释放

缓冲流

  1. 就是个包装流,目的是起到缓冲的作用,提升io性能

  2. 字节流的缓冲流

    • BufferedInputStream //缓冲输入流
      BufferedOutputStream //缓冲输出流
      
  3. 字符流的缓冲流

  • BufferedReader 字符输入缓冲流
  • BufferedWriter 字符输出缓冲流
  1. 目的:习惯的去操作我们的byte char数组,先与内存进行交互,然后达到一定量之后,再去与磁盘交互。减少与磁盘交互的次数,提高性能。

字符编码

  1. 字符编码的发展流程

    • 一开始只能认识数字 0 1,后来可以识别一些字母 (ASCII 美国标准信息交换码)

    • 随着计算机的普及,很多国家将自己的字符引入计算机,汉字,一个字节的存储范围太小,两个字节来存储汉字

      中文的二进制最高位规定为1 (负数) GB2312编码 —GBK

    • 汉字在其他国家的编码问题,别人不认识,显示出乱码的情况。需要统一的编码, Unicode编码

  2. 常用的字符编码集

    • ASCII:占一个字节,包含128个符号,不能表示汉字
    • ISO-8859-1(lantin-1)占一个字节:收录西欧的语言,不能表示汉字
    • GB-312(ANSI):占两个字节
    • UTF-8:(存储汉字占三个字节)针对Unicode可变长字符编码,成为后来的通用编码(IETF要求所有的互联网协议都使用)
  3. 字符的编码以及解码(使用相同的编码规范)

    • 编码:把字符串转换成byte数组
    • 解码:把byte数组转换成字符串

合并流

SequenceInputStream

//创建两个流对象,以供合并
FileInputStream inputStream1 = new FileInputStream("D:\\D-Test\\aaaa.txt");
FileInputStream inputStream2 = new FileInputStream("D:\\D-Test\\bbbb.txt");
//调用合并流方法
SequenceInputStream sequenceInputStream = new SequenceInputStream(inputStream1,inputStream2);
//读取
byte[] bytes = new byte[1200];
int length = -1;
while ((length = sequenceInputStream.read(bytes))!=-1){
    System.out.println(new String(bytes, 0, length));
}

sequenceInputStream.close();

对象流

  1. 序列化以及反序列化

    • 序列化:把我们堆内存中的java对象数据,存储到磁盘中去,或者给其他的网络节点使用
    • 反序列化:把磁盘文件的数据恢复成一个java对象的过程
  2. 为什么我们要使用序列化?

    • 在分布式系统里面,数据的共享都需要使用序列化,(redis)
    • 服务钝化:把不常用的对象存储到磁盘中去,节约内存开销
    • 使用json传输的时候
  3. 做序列化和反序列化的要求:必须去实现java.io.Serializable 接口

    • java中大多数的类都先实现了序列化接口的
  4. 对象流

    • 序列化:ObjectInputStream
    • 反序列化:ObjectOutputStream
     public static void main(String[] args) throws IOException, ClassNotFoundException {
            File file = new File("D:\\D-Test\\obj.txt");
    //        writeObject(file);
            readObject(file);
        }
        //序列化操作
        public static void writeObject(File file) throws IOException {
            ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file));
            outputStream.writeObject(new Student("王曼七",24));
            outputStream.close();
        }
    
        //反序列化操作
        public static void readObject(File file) throws IOException, ClassNotFoundException {
            ObjectInputStream InputStream = new ObjectInputStream(new FileInputStream(file));
            Object o = InputStream.readObject();
            Student stu = (Student)o;
            System.out.println(stu.getName() + "," + stu.getAge());
            InputStream.close();
        }
    
  5. 常见错误(NotSerializableException)实现序列化接口

  6. 序列化版本号的作用:相当于一个密码,引入了版本号,避免因为升级导致版本不兼容的问题。

打印流

  1. PrintStream 字节流

  2. PrintWrite 字符流

  3. 格式化输出

    String name;
    int age;
    Object[] obj = {"王曼七",24};
    //设置格式
    String s = "姓名:%s ,年龄:%d ";
     System.out.printf(s,obj);//姓名:王曼七 ,年龄:24 
    

Properties 加载配置文件

    public static void main(String[] args) throws IOException {
        //创建properties对象
        Properties properties = new Properties();
        //创建一个输入流
        FileInputStream inputStream = new FileInputStream
                ("D:\\idea_workspace\\day16\\src\\cn\\xiaojun\\practice\\conf\\db.properties");
        properties.load(inputStream);
        System.out.printf("url:%s",properties.getProperty("url"));
        System.out.printf("用户名:%s",properties.getProperty("username"));
        System.out.printf("密码:%s",properties.getProperty("password"));
    }

NIO

  1. jdk1.4开始提供,可以把一块磁盘文件映射到内存中去,java.nio
  2. 应用领域(云服务器中)
  3. jdk1.7提供了一个工具类---->files(操作文件类)
public static void main(String[] args) throws IOException {
    Files.copy(Paths.get("D:\\D-Test\\obj.txt"),
            new FileOutputStream("D:\\D-Test\\obj333.txt"));
}
  1. 与io的不同点
    • Channels Buffers(通道缓冲区):通过通道和缓冲区
    • 异步(Asynchronous):线程读取通道数据到缓冲区时,线程可以做其他事情
    • 选择器(Selectors): 用来监听多个通道,单线程可以去监听多个数据通道
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值