Explicación básica del flujo de Java-IO

Descripción general de OI

Los datos de los programas escritos antes están todos en la memoria. Una vez que el programa se ejecuta, los datos desaparecerán. Quiero usar los datos la próxima vez, pero ya no están. entonces que debemos hacer? ¿Puede guardar todos los datos después de la operación y luego leerlos y continuar usándolos cuando el programa se inicie la próxima vez? De hecho, para almacenar datos de forma persistente, es necesario almacenar los datos en la memoria de otros dispositivos persistentes (discos duros, CD-ROM, discos U, etc.)

  • Cuando necesita almacenar datos en la memoria de un dispositivo persistente, esta acción se denomina operación de salida (escritura) de salida
  • Cuando los datos del dispositivo persistente se leen en la memoria, esta acción se denomina entrada (lectura) Operación de entrada
  • Por lo tanto, llamamos a esta acción de entrada y salida una operación IO

Clasificación de la OI

Java IO generalmente consta de dos partes:

  1. Bloqueo de IO en el paquete java.io;
  2. IO sin bloqueo en el paquete java.nio, comúnmente llamado NewIO.

Los amigos que han estudiado los sistemas operativos saben que el cuello de botella del funcionamiento del sistema son generalmente las operaciones de E/S. En general, lleva mucho tiempo abrir un canal de E/S y es posible que no haya suficientes datos en el puerto, por lo que el método de lectura ha estado esperando. para leer el contenido del puerto, desperdiciando así una gran cantidad de recursos del sistema. ¡Alguien puede proponer el uso de tecnología de subprocesos múltiples en Java! Sin embargo, crear un subproceso en el proceso actual también requiere una cierta cantidad de tiempo y recursos del sistema, por lo que no es necesariamente deseable. La tecnología sin bloqueo de Java New IO adopta principalmente el modo Observer, es decir, hay un observador específico y un puerto IO de monitoreo, y si ingresan datos, la aplicación correspondiente será notificada de inmediato. De esta manera, evitamos crear múltiples hilos y también evitamos el tiempo de espera de lectura. Sin embargo, este artículo habla principalmente sobre el bloqueo de E/S de Java, que es el paquete que solemos usar.

El IO de Java consta principalmente de tres partes:

  1. Parte de transmisión: la parte principal de IO;
  2. Parte sin transmisión: incluye principalmente algunas clases que ayudan a la parte de transmisión, como: clase de archivo, clase RandomAccessFile y FileDescriptor y otras clases;
  3. Clases relacionadas con la seguridad en la parte de lectura de archivos, como: clase SerializablePermission. Y la clase del sistema de archivos relacionado con el sistema operativo local, como: clase FileSystem y clase Win32FileSystem y clase WinNTFileSystem.

La parte de transmisión se puede resumir así: dos corresponden a un puente.

Dos contrapartes se refieren a:

  1. 字节流(Byte Stream)和字符流(Char Stream)的对应;
  2. 输入和输出的对应。一个桥梁指:从字节流到字符流的桥梁。对应于输入和输出为InputStreamReader和OutputStreamWriter。

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

  1. 介质流(Media Stream或者称为原始流Raw Stream)――主要指一些基本的流,他们主要是从具体的介质上,如:文件、内存缓冲区(Byte数组、Char数组、StringBuffer对象)等,读取数据;
  2. 过滤流(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对象
复制代码

路径的分类

  1. 绝对路径, 带盘盘符 E:\work\a.txt
  2. 相对路径, 不带盘符 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学习视频

Java基础:

Java300集,Java必备优质视频_手把手图解学习Java,让学习成为一种享受

Java项目:

【Java游戏项目】1小时教你用Java语言做经典扫雷游戏_手把手教你开发游戏

【Java毕业设计】OA办公系统项目实战_OA员工管理系统项目_java开发

Supongo que te gusta

Origin juejin.im/post/7085277446802505735
Recomendado
Clasificación