I/O流

I/O概述

I/O是Input/Output的缩写,表示输入输出。对于内存来说,从内存中取出数据写入到磁盘中的操作是输出,也就是写。从磁盘中读取数据到内存中是输入的操作,也就是读。
I/O流根据操作数据的最小单位,分为字符流和字节流。又可以根据是否直接对文件资源进行读写操作,分为节点流和处理流。
下面以java.io包为基础,学习I/O流的内容。

1. 继承结构

在这里插入图片描述

2.类的概述
2.1 File类

File类是对文件和目录的抽象。它可以用来表示一个文件或路径。I/O流操作目标就是系统中的文件。

**
 * Description:File类
 * 概述:File类是对文件和路径的抽象。
 * 1.静态成员。
 *      pathSeperator:路径分隔符。windows:分号; linux:冒号:
 *      seperator:名称分隔符。windows:反斜杠/ linux:正斜杠\
 *      作用:用于替代路径中写死的分隔符,使程序更加灵活。
 * 2.构造方法
 * 概述:在创建File对象时,路径可以真实存在也可以不存在;路径可以是相对路径也可以是绝对路径;
 * 路径可以是文件夹结尾也可以是文件结尾;并不影响File对象的创建
 *      2.1 使用指定路径作为参数
 *          File file = new File(String pathName);
 *      2.2 使用2个指定路径,拼接后作为文件路径
 *          File file = new File(String parent,String child);
 *      2.3 使用一个file对象,和一个路径名
 *          File file = new File(file parent,String child);
 * 3.其它方法
 *     3.1 创建功能
 *      3.1.1 创建文件对象
 *          boolean createNewFile();
 *      3.1.2 创建单级文件夹对象
 *          boolean mkDir();
 *      3.1.3 创建多级的文件夹对象
 *          boolean mkDirs();
 *      3.2 删除功能
 *       3.2.1 删除文件。
 *          delete();该方法会从磁盘上直接删除文件,不会进入回收站,只有在文件路径正确时,才会删除。
 *          如果目标问价夹下还有子文件,不会删除。
 *          deleteOnExit():在jvm停止后,才删除文件。
 *      3.3 获取信息(查询)功能
 *       3.3.1 获取文件路径
 *       3.3.2 获取父File的信息
 *       3.3.3 获取文件名称
 *       3.3.4 获取文件夹下的子文件名称
 *       3.3.5 获取子文件File
 *      3.4 判断功能
 *       3.4.1 判断文件是否存在
 *       3.4.2 是文件还是文件夹
 *       3.4.3 判断文件是否可写、可读、隐藏。
 * Date-Of-Create:2020/7/6-9:07
 */
public class FileDemo {
    public static void main(String[] args) throws IOException {
        //静态变量
        /*sep();*/
        //构造函数
        /*cons();*/
        //创建功能
        /*mk();*/
        //删除文件或者文件夹
        /*delete();*/
        //获取对象信息
        /*getInfo();*/
        //判断功能
        check();
    }

    private static void check() {
        String pathName = "C:\\Users\\aipande\\Desktop\\testDemo\\IO\\abc\\def";
        File file = new File(pathName);
        //判断是否存在
        /*System.out.println(file.exists());
        if(!file.exists()){
            file.mkdirs();
        }*/
        //判断是文件还是文件夹,对于不是实际存在的文件,无法判断是文件还是文件夹,注意不能根据文件路径判断是文件还是文件夹
        System.out.println(file.isDirectory());
    }

    private static void getInfo() throws IOException {
        String pathName = "C:\\Users\\aipande\\Desktop\\testDemo\\IO\\abc\\def";
        File file = new File(pathName);
        //获取文件绝对路径
        System.out.println(file.getAbsolutePath());
        //获取构造时传入的路径
        System.out.println(file.getPath());
        //父路径
        System.out.println(file.getParent());
        //父File对象。在给定一个路径,创建文件的时候,可以先使用该方法获取父File对象,
        //判断是否存在exsit(),如果不存在,再调用mkDirs()方法,避免父File文件夹不存在的问题
        System.out.println(file.getParentFile());
        //获取文件名称
        System.out.println(file.getName());
        //获取规范路径,没啥特别的用处,貌似和获取绝对路径的结果相同
        System.out.println(file.getCanonicalPath());
        //遍历文件夹,这里可以使用FileFilter过滤
        File[] files = file.listFiles();
        String[] fileName = file.list();
    }

    private static void delete() {
        String pathName = "C:\\Users\\aipande\\Desktop\\testDemo\\IO\\abc\\def";
        File file = new File(pathName);
        System.out.println(file.delete());
    }

    private static void mk() throws IOException {
        StringBuffer buffer = new StringBuffer();
        String sep = File.separator;
        buffer.append("C:").append(sep).append("Users").append(sep).append("aipande")
                .append(sep).append("Desktop").append(sep).append("testDemo").append(sep).append("IO").append(sep)
                .append("abc").append(sep).append("def");
        System.out.println(buffer.toString());
        File file = new File(buffer.toString());
        //创建文件,文件之前的所有文件夹必须已存在,否则抛出IO异常:系统找不到指定路径。
        //file.createNewFile();
        //创建单级文件夹,只能创建最后一级文件夹,如果最后一级文件夹的前置文件夹不存在,那么不会创建文件夹
        //file.mkdir();
        //创建多级文件夹,如果最后一级文件夹的前置文件夹不存在,那么也会创建前置文件
        file.mkdirs();
    }


    private static void cons() {
        String path = "C:\\Users\\aipande\\Desktop\\testDemo\\IO";
        File file = new File(path);
        File file1 = new File(path,"abc.txt");
        File file2 = new File(file,"def.txt");

        System.out.println(file);
        System.out.println(file1);
        System.out.println(file2);
    }

    public static void sep(){
        //获取系统路径分隔符
        String pathSep = File.pathSeparator;
        System.out.println(pathSep);
        //获取名称分隔符
        String sep = File.separator;
        System.out.println(sep);

        //用于替换路径中的分隔符
        StringBuffer path = new StringBuffer();
        path.append("C:").append(sep).append("new").append(sep);
        System.out.println(path);
    }
2.2 字节流

所有InputStream的子类都是输入字节流,所有OutputStream的子类都是字节输出流。
InputStream:抽象类,是所有字节输入流的超类。

//关闭流,释放资源
public void close();
//读取单个字节,读取下一个字节,返回该字节的int值(int类型有4个字节,将byte类型前的字节以0补齐的值,返回)
public int read();
//最多读取bytes.length个字节到数组中,返回值为读取的字节个数,如果没有可读字节,返回-1
public int read(byte[] bytes);
//最多读取len个字节,放到数组的指定位置,返回读取的字节个数
public int read(byte[] bytes,int offSet,int len);
//在流中做一个标记,该方法一般配合reset()方法使用
public void mark(int readlimit)
//将流重新定位到上一个标记的地方,可以实现重复读取字节
public void reset()

OutputStream:抽象类,是所有字节输出流的超类。

//关闭流,释放资源
public void close();
//写入一个字节,int类型由4个字节组成,这里只会取i低8位写入文件中。
public void write(int i);
//写入多个字节,将字节数组中的元素都写入文件中。
public void write(byte[] bytes);
//写入多个字节,从off位置开始,写入len个字节到文件中
public void write(byte[] bytes,int off,int len);
//刷新方法。如果输出流有缓冲区,调用该方法,会将缓冲区中的所有数据写入到文件中,注意,有缓冲区的输出流才有必要使用该方法
public void flush();
2.2.1 FileInputStream 和 FileOutputStream

FileInputStream:文件字节输入流,以字节为单位读取文件中的数据。
FileOutputStream:文件字节输出流,以字节为单位写入磁盘上的文件中。

FileInputStream:
1.构造方法

  • 因为是读取文件,所以在创建对象时,需要指定源文件(从哪里读),可以使用字符串路径,也可以使用File对象。
  •  1.1 FileInputStream fis = new FileInputStream(String pathName);
    
  •  1.2 FileInputStream fis = new FileInputStream(File file);
    
    上面两种构造方法,实质是一样的:
    //源码。判断路径是否为空,不为空则创建一个File对象,再调用FileInputStream(File file);
    public FileInputStream(String name) throws FileNotFoundException {
        this(name != null ? new File(name) : null);
    }
    
  • 2.其它方法
  • 概述:每个字节流再创建的时候,在字节流的头部都有一个指针,调用read方法时,会将指针后移,再次调用read方法会从指针的位置向后读取
  •  2.1 public int read();读取下一个字节,返回该字节的int值(int类型有4个字节,将byte类型前的字节以0补齐的值,返回int值)
    
  •  2.2 public int read(byte[] bytes);最多读取bytes.length个字节到数组中,返回值为读取的字节个数,如果没有可读字节,返回-1
    
  •  2.3 public int read(byte[] bytes,int offSet,int len);最多读取len个字节,放到数组的指定位置,返回读取的字节个数
    
  • 3.关闭流,释放资源的方法
  •  close();流关闭以后,就不能再读取字节了。
    

FileOutputStream:

  • 1.构造方法
  • 因为是写入,所以需要知道目标文件的地址,即往哪里写的问题。注意:在创建FileOutputStream对象时,如果目标文件不存在,会先尝试去创建目标文件。但如果目标文件路径表示的是文件夹、或者是文件但是无法创建,会抛出IO异常。
  • 1.1 FileOutputStream fos = new FileOutputStream(String pathName,boolean append);
  • pathName:指定文件的路径。
    
  • append:如果为true,表示在写入时,会将数据添加到原文件中。否则,则会覆盖原文件的内容。
    
  • 1.2 FileOutputStream fos = new FileOutputStream(String pathName);
  • pathName:指定文件的路径。append默认为false。
    
  • 1.3 FileOutputStream fos = new FileOutputStream(File file,boolean append);
  • 与第一种构造方法本质是一样的,只是第一种方法执行了一个new File(pathName)的过程。
    
  • 1.4 FileOutputStream fos = new FileOutputStream(File file);
  • 与第二种方法本质一样。	
    
  • 2.其他方法
  • 主要是继承自OutputStream的几种方法。参考OutputStream的内容。

小结:
1.flush方法和close方法的区别?
flush方法会将缓冲区中的数据写入文件,但不会关闭流。close方法也会将缓冲区中的内容写到文件中,但是会关闭流。流关闭后,无法再写入数据。

2.2.2 ObjectInputStream和ObjectOutputStream

首先介绍对象的序列化和反序列化:
序列化:将对象转换成字节序列的过程。
反序列化:将字节序列恢复成对象的过程。

ObjectInputStream:对象字节输入流。作用:对象的反序列化,即将字节序列读取到内存中,并恢复成对象。
ObjectOutputStream:对象字节输出流。对象的序列化,将对象以字节的形式保存或传输。

ObjectInputStream:
构造方法:
1.ObjectOutputStream oos = new ObjectOutputStream(OutputStream out);
特殊方法:
public Object readObject();从字节流中读取一个对象。
ObjectOutputStream:
1.ObjectOutputStream oos = new ObjectOutputStream(OutputStream out);
特殊方法:
public void writeObject(Object object);将对象写入文件。
小结:
1.类如果要实现序列化,必须实现Serializable接口。
2.可以使用transient关键字修饰变量,使该变量不会被序列化。(作用类似于static)

2.2.3 BufferedInputStream和BufferedOutputStream

BufferedInputStream:缓冲字节输入流。就是在字节输入流的基础上,加了一个缓冲区,以提高字节读取的效率。
BufferedOutputStream:缓冲字节输出流。同上。
对于缓冲输出流来说,如果想要立即看到写入效果,可以调用flush方法。

BufferedInputStream
因为是对字节输入流添加缓冲功能,因此,需要一个字节输入流作为构造参数。
构造方法:

  • 1.BufferedInputStream bis = new BufferedInputStream(InputStream inputStream);//使用默认大小的直接缓冲数组
  • 2.BufferedInputStream bis = new BufferedInputStream(InputStream inputStream,int size);//指定缓冲字节数组的大小

BufferedOutputStream
构造方法:

  • 1.BufferedOutputStream bos = new BufferedOutputStream(OutputStream os);
  • 2.BufferedOutputStream bos = new BufferedOutputStream(OutputStream os,int size);
2.3 字符流

Reader:所有字符输入流的超类。
Writer:所有字符输出流的超类。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值