写点什么

Java 基础——IO 流

作者:java易二三
  • 2023-07-22
    湖南
  • 本文字数:4690 字

    阅读完需:约 15 分钟

IO 概述

        之前写过的程序,数据都是在内存中,一旦程序运行结束,这些数据都没有了,等下次再想使用这些数据,可是已经没有了。那怎么办呢?能不能把运算完的数据都保存下来,下次程序启动的时候,再把这些数据读出来继续使用呢?其实要把数据持久化存储,就需要把内存中的数据存储到内存以外的其他持久化设备(硬盘、光盘、U 盘等)上

当需要把内存中的数据存储到持久化设备上这个动作称为输出(写)Output 操作

当把持久设备上的数据读取到内存中的这个动作称为输入(读)Input 操作

因此我们把这种输入和输出动作称为 IO 操作

IO 的分类

Java IO 一般包含两个部分:

java.io 包中堵塞型 IO;

java.nio 包中的非堵塞型 IO,通常称为 NewIO。

        学过操作系统的朋友都知道系统运行的瓶颈一般在于 IO 操作,一般打开某个 IO 通道需要大量的时间,同时端口中不一定就有足够的数据,这样 read 方法就一直等待读取此端口的内容,从而浪费大量的系统资源。有人也许会提出使用 java 的多线程技术啊!但是在当前进程中创建线程也是要花费一定的时间和系统资源的,因此不一定可取。Java New IO 的非堵塞技术主要采用了 Observer 模式,就是有一个具体的观察者和=监测 IO 端口,如果有数据进入就会立即通知相应的应用程序。这样我们就避免建立多个线程,同时也避免了 read 等待的时间。不过本篇主要讲述 java 的堵塞型 IO,就是我们通常应用的那个包。

Java 的 IO 主要包含三个部分:

流式部分――IO 的主体部分;

非流式部分――主要包含一些辅助流式部分的类,如:File 类、RandomAccessFile 类和 FileDescriptor 等类;

文件读取部分的与安全相关的类,如:SerializablePermission 类。以及与本地操作系统相关的文件系统的类,如:FileSystem 类和 Win32FileSystem 类和 WinNTFileSystem 类。

流式部分可以概括为:两个对应一个桥梁。

两个对应指:

字节流(Byte Stream)和字符流(Char Stream)的对应;

输入和输出的对应。一个桥梁指:从字节流到字符流的桥梁。对应于输入和输出为 InputStreamReader 和 OutputStreamWriter。

在流的具体类中又可以具体分为:

        介质流(Media Stream 或者称为原始流 Raw Stream)――主要指一些基本的流,他们主要是从具体的介质上,如:文件、内存缓冲区(Byte 数组、Char 数组、StringBuffer 对象)等,读取数据;

        过滤流(Filter Stream)――主要指所有 FilterInputStream/FilterOutputStream 和 FilterReader/FilterWriter 的子类,主要是对其包装的类进行某些特定的处理,如:缓存等。

File 类

我们先从 file 类学起,file 类是文件和目录路径名的抽象表示。

File 类的构造函数

通过构造方法创建 File 对象

/**

* 通过构造方法创建 File 对象

*/

public static void test1() {

    // File 构造函数演示

    String pathName = "e:\\test\\Hello.java";

    // 注意:可以封装不存在文件或者文件夹,变成对象。

    File file1 = new File(pathName);

    System.out.println("file1 = " + file1);

    File file2 = new File("e:\\test", "Hello.java");

    System.out.println("file2 = " + file2);

    // 将 parent 封装成 file 对象

    File dir = new File("e:\\test");

    File file3 = new File(dir, "Hello.java");

    System.out.println("file3 = " + file3);

    //file1 = e:\test\Hello.java

    //file2 = e:\test\Hello.java

    //file3 = e:\test\Hello.java

}

File 类获取文件相关信息

创建完了 File 对象之后,那么 File 类中都有如下常用方法,可以获取文件相关信息

/**

* File 类获取文件相关信息

*/

public static void test2() {

    // 创建文件对象

    File file = new File("Test2.java");

    // 获取文件的绝对路径,即全路径

    String absPath = file.getAbsolutePath();

    // File 中封装的路径是什么获取到的就是什么

    String path = file.getPath();

    // 获取文件名称

    String fileName = file.getName();

    // 获取文件大小

    long size = file.length();

    System.out.println("absPath = " + absPath);

    System.out.println("path = " + path);

    System.out.println("fileName = " + fileName);

    System.out.println("size = " + size);

    //absPath = F:\JetBrains\myProject\springboot2-examples\Test2.java

    //path = Test2.java

    //fileName = Test2.java

    //size = 0

}

文件和文件夹的创建与删除等

/**

* 文件和文件夹的创建与删除等

*/

public static void test3() throws IOException {

    // 对文件或者文件夹进行操作

    File file = new File("e:\\test3.txt");

    // 创建文件,如果文件不存在,创建 true。 如果文件存在,则不创建 false。 如果路径错误,IOException。

    boolean b1 = file.createNewFile();

    System.out.println("b1 = " + b1);

    // 删除文件操作 - 慎用

    boolean b2 = file.delete();

    System.out.println("b2 = " + b2);

    // 判断文件是否存在

    boolean b3 = file.exists();

    System.out.println("b3 = " + b3);

    // 对目录操作 创建、删除、判断

    File dir = new File("e:\\abc");

    // mkdir()创建单个目录;  mkdirs()创建多级目录

    boolean b4 = dir.mkdir();

    System.out.println("b4 = " + b4);

    // 删除目录时,如果目录中有文件,无法直接删除

    // 只有将目录中的内容都删除后,保证该目录为空。这个目录才可以删除。

    boolean b5 = dir.delete();

    System.out.println("b5 = " + b5);

    // 要判断是否是文件还是目录,必须先判断存在

    File file1 = new File("e:\\hello.txt");

    // file1.mkdir();//file1.createNewFile(); // 要判断是否是文件还是目录,先判断存在。

    System.out.println("file1.isFile() = " + file1.isFile());

    System.out.println("file1.isDirectory() = " + file1.isDirectory());


    //b1 = true

    //b2 = true

    //b3 = false

    //b4 = true

    //b5 = true

    //file1.isFile() = false

    //file1.isDirectory() = false

}

获取目录下的所有文件和文件夹

        文件都存放在目录(文件夹)中,那么如何获取一个目录中的所有文件或者目录中的文件夹呢?那么我们先想想,一个目录中可能有多个文件或者文件夹,那么如果 File 中有功能获取到一个目录中的所有文件和文件夹,那么功能得到的结果要么是数组,要么是集合。

/**

* 获取目录下的所有文件和文件夹

*/

public static void test4() throws IOException {

    File dir = new File("e:\\java_code");

    File file1 = new File(dir, "aaa");

    file1.mkdirs();

    File file2 = new File(dir, "a.txt");

    file2.createNewFile();

    //获取的是目录下的当前的文件以及文件夹的名称。

    String[] names = dir.list();

    for (String name :

            names) {

        System.out.println("name = " + name);

    }

    //获取目录下当前文件以及文件对象,只要拿到了文件对象,那么就可以获取其中想要的信息

    File[] files = dir.listFiles();

    for (File file :

            files) {

        System.out.println("file = " + file);

    }

    //name = a.txt

    //name = aaa

    //file = e:\java_code\a.txt

    //file = e:\java_code\aaa

}

文件过滤器

        通过 listFiles()方法,我们可以获取到一个目录下的所有文件和文件夹,但能不能对其进行过滤呢?比如我们只想要一个目录下的指定扩展名的文件,或者包含某些关键字的文件夹呢

        我们是可以先把一个目录下的所有文件和文件夹获取到,并遍历当前获取到所有内容,遍历过程中在进行筛选,但是这个动作有点麻烦,Java 给我们提供相应的功能来解决这个问题

    /**

    * 文件过滤器

    * 获取扩展名为.java 所有文件

    */

    public static void test5() {

        // 创建 File 对象

        File file = new File("e:\\java_code");

        // 获取指定扩展名的文件,由于要对所有文件进行扩展名筛选,因此调用方法需要传递过滤器

        File[] files = file.listFiles(new MyFileFilter());

        // 遍历获取到的所有符合条件的文件

        for (File f :

                files) {

            System.out.println("f = " + f);

        }

        // f = e:\java_code\b.java

    }

/**

* 定义类实现文件名称 FilenameFilter 过滤器

*/

class MyFileFilter implements FilenameFilter {

    @Override

    public boolean accept(File dir, String name) {

        return name.endsWith(".java");

    }

}

值得一提的是 我们要注意这个用法 只能是下一级目录,不能说是 2 级 就比如例子中的 必须要是 java_code/下的,就是说 java_code/aaa/下的 bbb.java 也是找不到的

递归打印所有子目录中的文件路径

/**

* 递归打印所有子目录中的文件路径

*/

public static void test6() {

    File file = new File("e:\\java_code");

    getFileAll(file);

    //file = e:\java_code\a.txt

    //file = e:\java_code\aaa\b.java

    //file = e:\java_code\b.java

}

public static void getFileAll(File file) {

    File[] files = file.listFiles();

    // 遍历当前目录下的所有文件和文件夹

    for (File f :

            files) {

        // 判断当前遍历到的是否为目录

        if (f.isDirectory()) {

            // 是目录,继续获取这个目录下的所有文件和文件夹

            getFileAll(f);

        } else {

            // 不是目录,说明当前 f 就是文件,那么就打印出来

            System.out.println("file = " + f);

        }

    }

}

File 总结

File: 文件和目录路径名的抽象表示形式

构造方法

public File(String pathname) 通过给定的文件或文件夹的路径,来创建对应的 File 对象

public File(String parent, String child) 通过给定的父文件夹路径,与给定的文件名称或目录名称来创建对应的 File 对象

public File(File parent,  String child)通过给定的 File 对象的目录路径,与给定的文件夹名称或文件名称来创建对应的 File 对象

路径的分类

绝对路径, 带盘盘符  E:\\work\\a.txt

相对路径, 不带盘符  work\\a.txt 注意: 当指定一个文件路径的时候,如果采用的是相对路径,默认的目录为 项目的根目录 

常用方法

public boolean createNewFile()创建文件

返回值为 true, 说明创建文件成功

返回值为 false,说明文件已存在,创建文件失败

public boolean mkdir() 创建单层文件夹

创建文件夹成功,返回 true

创建文件夹失败,返回 false

public boolean mkdirs() 创建多层文件夹

public boolean delete()

删除此抽象路径名表示的文件或目录

如果此路径名表示一个目录,则该目录必须为空才能删除

public boolean isDirectory() 判断是否为文件夹

public boolean isFile() 判断是否为文件

public boolean exists() 判断 File 对象对应的文件或文件夹是否存在

public String getAbsolutePath() 获取当前 File 的绝对路径

public String getName() 获取当前 File 对象的文件或文件夹名称

public long length() 获取当前 File 对象的文件或文件夹的大小(字节)

public File[] listFiles() 获取 File 所代表目录中所有文件或文件夹的绝对路径

用户头像

java易二三

关注

还未添加个人签名 2021-11-23 加入

还未添加个人简介

评论

发布
暂无评论
Java基础——IO流_Java_java易二三_InfoQ写作社区