【动力节点 Java进阶学习笔记】第六章 IO流

IO流和FIle类总结

1、IO流总结

在这里插入图片描述

2、File类中方法总结

在这里插入图片描述

IO流和FIle类学习笔记

1、Java流概述和IO流的分类

       流的分类:输入流、输出流
                        字节流(什么类型的文件都可以读取)、字符流(只能读取纯文本文件)
       java IO流四大家族: java.io.InputStream 字节输入流
                                         java.io.OutputStream 字节输出流
                                         java.io.Reader 字符输入流
                                         java.io.Writer 字符输出流
       所有的流都实现了:java.io.Closeable接口,都是可关闭的,都有close()方法。
       所有的输出流都实现了:java.io.Flushable接口,都是可刷新的,都有flush()方法。
       java.io包下需要掌握的流有16个:可见上面的总结部分

2、FileInputStream的使用:按字节和byte数组两种方式读取文件内容

       2.1 按字节读取文件内容,返回字节本身,如果已到达文件末尾,则返回 -1。
                                   -->内存和硬盘交互太频繁
              int readData;
              while((readData = fis.read()) != -1){
                     System.out.print(readData);
              }
       2.2 往byte数组中读:read(byte[] b) ,返回读取到的字节数量,数据存储在数组中
                                   —>减少硬盘和内存的交互,提高程序的执行效率
              byte[] bytes = new byte[4];
              int readData = 0 ;
              while((readData = fis.read(bytes))!= -1){
                     System.out.print(new String(bytes, 0, readData));
              }
       2.3 FileInputStream类的其它常用方法:
              int available():返回流当中剩余的没有读到的字节数量
              long skip(long n):跳过几个字节不读。

3、FileOutputStream的使用:覆盖方式和追加方式写入数组中内容

       默认是通过覆盖的方式写入,文件不存在会自动创建:
              new FileOutputStream();
       以追加方式写入:
              new FileOutputStream(, true);
       写入的方法:
              (1)写入数组全部内容 fos.write(bytes);
              (2)写入部分数组内容 fos.write(bytes, 0, 2)
              (3)写入字符串 byte[] bs = s.getBytes();  fos.write(bs);
       写完之后,最后一定要刷新:fos.flush();

4、FileReader的使用

       使用char数组:
              char[] chars = new char[4];
              reader.read(chars)

5、FileWriter的使用

       可使用char数组,也可直接使用String
              void write(char cbuf[])
              void write(char cbuf[], int off, int len)
              void write(String str)
              void write(String str, int off, int len)

6、缓冲流BufferedReader和BufferedWriter的使用以及转换流的使用、节点流和包装流

       特点:可以不需要数组,也可以逐行读取,相比文件流速度更快
       BufferedReader:
              BufferedReader br = new BufferedReader(new FileReader(" "));
              BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(" ")));
              readLine()方法读取一个文本行,但不带换行符。返回String类型,如果已到达流末尾,则返回 null
        BufferedWriter:
              BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(" ", true)));
       当一个流的构造方法中需要一个流的时候,这个被传进来的流叫做: 节点流
       外部负责包装的这个流,叫做:包装流,还有一个名字叫做: 处理流
        关闭流close():对于包装流来说,只需要关闭最外层流就行,里面的节点流会自动关闭

7、数据流DataOutputStream和DataInputStream的使用

       DataOutputStream可以将数据连同数据的类型一并写入文件:writeByte()、writeShort()…
       DataOutputStream写的文件,只能使用DataInputStream去读。并且读的时候你需要提前知道写入的顺序。
       读的顺序需要和写的顺序一致,才可以正常取出数据:readByte()、readShort()…

8、PrintStream的使用

       默认输出到控制台。
       可以改变标准输出流的输出方向,达到日志输出重定向的效果:
              // 标准输出流不再指向控制台,指向“log”文件。
              PrintStream printStream = new PrintStream(new FileOutputStream(“log”));
               // 修改输出方向,将输出方向修改到"log"文件。
              System.setOut(printStream);
              System.out中out属性为一个printStream对象

9、File类概述和常用方法

       File对象代表什么:文件和目录路径名的抽象表示形式。
       File类中常用的方法:
              创建File对象:new File(“D:\file”);
              判断文件或目录是否存在:exists()
              创建新文件: createNewFile()
              创建新目录:mkdir() 、mkdirs()
              获取文件绝对路径:getAbsolutePath()
              获取文件名:getName()
              获取当前目录下所有的子文件:File[] | listFiles()
              获取当前目录下所有的子文件:String[] | list()
              判断是否是一个目录:isDirectory()
              判断是否是一个文件:isFile()

       经典实践:某一文件夹下所有文件的复制,参见本文最后面附录的代码

10、序列化和反序列化的概念、Serializable接口和作用、如何序列化和反序列化对象

       序列化:Serialize 将java对象存储到内存中,拆分对象存储,即将java对象的状态保存下来的过程
       反序列化:Deserialize 将硬盘上的数据重新恢复到内存当中,恢复成java对象(组装对象)

  • 参与序列化和反序列化的对象,必须实现Serializable接口。
  • Serializable这个标志接口是给java虚拟机参考的,java虚拟机看到这个接口之后,会为该类自动生成一个序列化版本号。
  • 序列化版本号的作用:Java虚拟机区分类
  • 凡是一个类实现了Serializable接口,建议给该类提供一个固定不变的序列化版本号。这样,以后这个类即使代码修改了,但是版本号不变,java虚拟机会认为是同一个类。
  • 序列化对象:ObjectOutputStream(OutputStream out) writeObject()
  • 反序列化对象:ObjectOutputStream(OutputStream out) readObject()
  • 可以将对象放到集合当中一次序列化多个对象:writeObject()
  • transient关键字表示游离的,该关键字修饰的属性不参与序列化。

11、IO+Properties的联合应用实现配置文件的动态读取

       属性配置文件:以.properties结尾的文件,内容格式为key1=value
       利用Properties的load()方法将文件中的数据加载到Map集合中:
              load(Reader reader) load(InputStream inStream)
       然后再用getProperty方法对配置文件中的数据进行读取

附录:某一文件夹下所有文件的复制–代码实现

备注:简单测试了一下正常场景没发现问题,可供参考,可能存在场景覆盖不全的问题,如果发现代码问题请帮忙指出,我会及时改正,谢谢!

package com.javalearn.javase.review.io;

import java.io.*;

public class CopyAll {
    public static void main(String[] args) {
        File srcdir = new File("G:\\学习\\java\\test2");
        File dstDir = new File("G:\\学习\\java\\test1");
        copyAll(srcdir, srcdir, dstDir);
    }

    public static void copyAll(File copyDir, File srcDir, File dstDir) {
        if (!dstDir.exists()){
            dstDir.mkdir();
        }
        if (srcDir.exists()) {
            if (copyDir.isFile()) {
                copyFile(copyDir, srcDir, dstDir);
                return;
            }
            File[] files = copyDir.listFiles();
//            if (files.length == 0){
//                copyDir(copyDir, srcDir, dstDir);
//                return;
//            }
            for (File file : files) {
                if (file.isDirectory()) {
                    copyDir(file, srcDir, dstDir);
                }
                copyAll(file, srcDir, dstDir);
            }
        }
    }

    //拷贝文件
    public static void copyFile(File srcFile, File srcDir, File dstDir) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(srcFile);
            String dstFilePath = null;
            if (srcFile.equals(srcDir)){
                dstFilePath = dstDir.getAbsolutePath() + "\\" + srcFile.getName();
            } else {
                dstFilePath = srcFile.getAbsolutePath().replace(srcDir.getAbsolutePath(), dstDir.getAbsolutePath());
            }
            fos = new FileOutputStream(dstFilePath);
            byte[] bytes = new byte[1024 * 1024];
            int readCount = 0;
            while ((readCount = fis.read(bytes)) != -1) {
                fos.write(bytes, 0, readCount);
            }
            fos.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //拷贝文件夹
    public static void copyDir(File srcSubDir, File srcDir, File dstDir) {
        String dstDirPath = srcSubDir.getAbsolutePath().replace(srcDir.getAbsolutePath(), dstDir.getAbsolutePath());
        File dstSubDir = new File(dstDirPath);
        if (!dstSubDir.exists()){
            dstSubDir.mkdir();
        }
    }
}

补充:IDEA生成 Serializable序列化UID的快捷键及其设置方法

可参考:https://blog.csdn.net/qq_41958123/article/details/87616704
设置方法:Fil–>Setting–>Editor–>Inspections–>Java–>Serialization issues–>勾选Serializable class without 'serialVersionUID’
在这里插入图片描述

调用快捷键:鼠标定位到类上,alt+enter 选择Add ‘serialVersionUID’ filed就会自动生成
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值