Notas de estudio: Capítulo avanzado de Java del programador Dark Horse (1) (Parte 4)

Introducción al lenguaje Java para los capítulos de dominio.

  1. Notas de estudio: Java-Basics (Parte 1)_blog-CSDN de blog de ljtxy.love
  2. Notas de estudio: Java-Intermedio (Parte 2)_Blog-CSDN de blog de ljtxy.love
  3. Notas de estudio: Java avanzado (tercera parte): se busca programador
  4. Notas de estudio: Capítulo avanzado de Java (1) (Parte 4) Blog-CSDN de _ljtxy.love
  5. Notas de estudio: Java-Avanzado (2) (Parte 5) - Se busca programador
  6. Notas de estudio: nuevas funciones del blog Blog-CSDN de Java8_ljtxy.love

Directorio de artículos

20.Transmisión de corriente

Resumen de notas:

  1. Descripción general: en Java 8, Stream es un mecanismo para procesar colecciones . Puede realizar varias operaciones en las colecciones ( filtrado , mapeo , clasificación, etc.) y generar nuevas colecciones, al tiempo que admite el procesamiento paralelo.

  2. Función: combinar expresiones Lambda para simplificar el funcionamiento de colecciones y matrices

  3. Pasos de uso:

    1. Obtener objeto de flujo Stream

      • Colección del sistema de recopilación: utilice el método predeterminado stream() para generar una secuencia, Stream stream() predeterminado

      • Colección del sistema de mapas: convierta el mapa en una colección de conjuntos y genere secuencias indirectamente

      • Matriz: genere una secuencia a través de la secuencia del método estático en la clase de herramienta Arrays

      • Múltiples datos dispersos del mismo tipo de datos: genere una secuencia a través del método estático de (valores T...) de la interfaz Stream

    2. Utilice métodos intermedios para procesar datos .

      • filtro : filtro

        list.stream().filter(new Predicate<String>() {
                   
                   
            @Override
            public boolean test(String s) {
                   
                   
                return s.startsWith("张");
            }
        })
        
      • límite : Obtener los primeros elementos

        list.stream().limit(3)
        
      • skip : salta los primeros elementos

        list.stream().skip(2)
        
      • distinto : deduplicación de elementos (tenga en cuenta que cuando se utiliza un objeto personalizado para la deduplicación, se basa en el código hash y los métodos iguales )

        list1.stream().distinct()
        
      • concat : fusiona dos secuencias a y b en una sola secuencia

        Stream.concat(list1.stream(),list2.stream())
        //注意:在使用时,此处使用Stream对象中的concat静态方法
        
      • mapa : convierte tipos de datos en la secuencia

        // Function<原本数据类型,需要转换的目标数据类型>
        list.stream().map(new Function<String, Integer>() {
                   
                   
            @Override
            public Integer apply(String s) {
                   
                   
                String[] arr = s.split("-");
                String ageString = arr[1];
                int age = Integer.parseInt(ageString);
                return age;
            }
        })
        
    3. Utilice finalizadores para procesar datos .

      • para cada uno : atravesar

        list.stream().forEach(new Consumer<String>() {
                   
                   
                    @Override
                    public void accept(String s) {
                   
                   
                        System.out.println(s);
                    }
                })
        
      • contar : estadísticas

        list.stream().count();
        
      • toArray : recopila datos de la secuencia y los coloca en una matriz

        list.stream().toArray(new IntFunction<String[]>() {
                   
                   
            @Override
            public String[] apply(int value) {
                   
                   
                return new String[value];
            }
        });
        
        System.out.println(Arrays.toString(arr));
        
      • recopilar : recopila datos en la secuencia y los coloca en una colección.

        Map<String, Integer> map = list.stream()
            .filter(s -> "男".equals(s.split("-")[1]))
            .collect(Collectors.toMap(
                new Function<String, String>() {
                   
                   
                    @Override
                    public String apply(String s) {
                   
                   
                        return s.split("-")[0];
                    }
                },
                new Function<String, Integer>() {
                   
                   
                    @Override
                    public Integer apply(String s) {
                   
                   
                        return Integer.valueOf(s.split("-")[2]);
                    }
                }
            ));
        

20.1 Descripción general

20.1.1 Definición

En Java 8, Stream es un mecanismo para procesar colecciones, que puede realizar diversas operaciones en las colecciones (filtrado, mapeo, clasificación, etc.) y generar nuevas colecciones, al tiempo que admite el procesamiento paralelo.

En pocas palabras, un Stream es un contenedor que se puede procesar varias veces y los elementos se pueden convertir y procesar mediante algunas operaciones en cadena. Las operaciones de flujo se dividen en operaciones intermedias y operaciones finales: la operación intermedia devuelve otro flujo y la operación final no devuelve un flujo, sino un resultado de cálculo.

El uso de Stream puede simplificar la implementación del código y, debido a sus capacidades de procesamiento paralelo, puede mejorar en gran medida la eficiencia de ejecución del código.

20.1.2 Pensamientos

imagen-20230425102635610

ilustrar:

​Filtra capa por capa para finalmente obtener el resultado deseado

20.1.3 Pasos de uso

  • Obtener transmisión en vivo
    • Cree una canalización y coloque datos en la canalización para prepararse para la operación.
  • camino medio
    • Operaciones en la línea de montaje.
    • Una vez completada una operación, puede continuar realizando otras operaciones
  • método final
    • Una secuencia solo puede tener un método finalizador
    • Es la última operación en el oleoducto.

20.2 Función

La función principal de Stream es realizar operaciones de recopilación y programación funcional de datos, lo que puede lograr una detección, clasificación, filtrado, agrupación, estadísticas y otras operaciones eficientes de datos.

20.3 Obtener la transmisión

imagen-20230425102937415

método de obtención:

  • Colección del sistema de recopilación: utilice el método predeterminado stream() para generar una secuencia, Stream stream() predeterminado

  • Colección del sistema de mapas: convierta el mapa en una colección de conjuntos y genere secuencias indirectamente

  • Matriz: generar una secuencia a través de la secuencia del método estático en matrices

  • Múltiples datos del mismo tipo de datos: genere una secuencia a través del método estático de (T... valores) de la interfaz Stream

Código de muestra:

public class StreamDemo {
    
    
    public static void main(String[] args) {
    
    
        //Collection体系的集合可以使用默认方法stream()生成流
        List<String> list = new ArrayList<String>();
        Stream<String> listStream = list.stream();

        Set<String> set = new HashSet<String>();
        Stream<String> setStream = set.stream();

        //Map体系的集合间接的生成流
        Map<String,Integer> map = new HashMap<String, Integer>();
        Stream<String> keyStream = map.keySet().stream();
        Stream<Integer> valueStream = map.values().stream();
        Stream<Map.Entry<String, Integer>> entryStream = map.entrySet().stream();

        //数组可以通过Arrays中的静态方法stream生成流
        String[] strArray = {
    
    "hello","world","java"};
        Stream<String> strArrayStream = Arrays.stream(strArray);
      
      	//同种数据类型的多个数据可以通过Stream接口的静态方法of(T... values)生成流
        Stream<String> strArrayStream2 = Stream.of("hello", "world", "java");
        Stream<Integer> intStream = Stream.of(10, 20, 30);
    }
}

ilustrar:

En colecciones , las colecciones de una sola columna pueden obtener la secuencia Stream a través del método .stream(). Las colecciones de dos columnas se pueden convertir primero en colecciones de una sola columna y luego recuperarlas.

En una matriz, la secuencia Stream se puede obtener mediante el método .stream() de la clase de herramienta Arrays.

En datos dispersos , la secuencia Stream se puede obtener mediante el método Stream.of ().

Tenga en cuenta que los datos dispersos deben ser del mismo tipo de datos y el tipo de parámetro en Stream.of () debe ser un tipo de datos de referencia. Si es un tipo de datos básico, la operación de boxeo automático no se completará, pero toda Los datos básicos serán El tipo se trata como un elemento.

20.4 Métodos intermedios

imagen-20230425104642136

20.4.1filtro()

ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰", "张翠山", "张良", "王二麻子", "谢广坤");
// filter   过滤  把张开头的留下,其余数据过滤不要
list.stream().filter(new Predicate<String>() {
    
    
    @Override
    public boolean test(String s) {
    
    
        //如果返回值为true,表示当前数据留下
        //如果返回值为false,表示当前数据舍弃不要
        return s.startsWith("张");
    }
}).forEach(s -> System.out.println(s));

/*	因为filter中的参数类型为函数式接口,
	而Predicate接口中又只有一个抽象方法test,
	因此可以通过Lambda方式进行简化	*/
list.stream()
    .filter(s -> s.startsWith("张"))
    .filter(s -> s.length() == 3)
    .forEach(s -> System.out.println(s)

20.4.2límite()

ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰", "张翠山", "张良", "王二麻子", "谢广坤");
list.stream().limit(3).forEach(s -> System.out.println(s)); // "张无忌", "周芷若", "赵敏"

20.4.3 saltar()

ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强");
list.stream().skip(2).forEach(s -> System.out.println(s)); // "赵敏", "张强"

20.4.4distinto()

ArrayList<String> list1 = new ArrayList<>();
Collections.addAll(list1, "张无忌","张无忌","张无忌", "张强", "张三丰", "张翠山", "张良", "王二麻子", "谢广坤");

// 此处并没有重写equals和hashCode方法,因为list的类型为String,Java已经完成了这两个方法的重写
list1.stream().distinct().forEach(s -> System.out.println(s));

ilustrar:

La capa inferior del método distintivo () es el nuevo HashSet, y HashSet necesita confiar en los métodos iguales y hashCode para la deduplicación.

imagen-20230425113033366

Aviso:

Si necesita deduplicar objetos personalizados, debe anular los métodos iguales y hashCode.

20.4.5concat()

ArrayList<String> list1 = new ArrayList<>();
Collections.addAll(list1, "张无忌","张无忌","张无忌", "张强", "张三丰", "张翠山", "张良", "王二麻子", "谢广坤");

ArrayList<String> list2 = new ArrayList<>();
Collections.addAll(list2, "周芷若", "赵敏");
Stream.concat(list1.stream(),list2.stream()).forEach(s -> System.out.println(s));

20.4.5mapa()

ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌-15", "周芷若-14", "赵敏-13", "张强-20", "张三丰-100", "张翠山-40", "张良-35", "王二麻子-37", "谢广坤-41");

// new Function<原本数据类型,需要转换到的数据类型>
list.stream().map(new Function<String, Integer>() {
    
    
    @Override
    public Integer apply(String s) {
    
    
        String[] arr = s.split("-");
        String ageString = arr[1];
        int age = Integer.parseInt(ageString);
        return age;
    }
}).forEach(s-> System.out.println(s));

System.out.println("------------------------");

// 同样,因为map中的参数为函数式接口,并且函数中只有一个抽象类方法,因此可以使用Lambda表达式进行简化
list.stream()
    .map(s-> Integer.parseInt(s.split("-")[1]))
    .forEach(s-> System.out.println(s));

Descripción: código fuente subyacente

imagen-20230425114353100

Aviso:

  • El método intermedio devuelve una nueva secuencia. La secuencia original solo se puede usar una vez (la secuencia se cerrará automáticamente después de usarse una vez). Se recomienda usar programación en cadena.
  • La modificación de los datos en Stream no afectará los datos de la colección o matriz original.

20.5 Método de terminación

imagen-20230425114628959

20.5.1 para cada ()

ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰", "张翠山", "张良", "王二麻子", "谢广坤");


//void forEach(Consumer action)           遍历

//Consumer的泛型:表示流中数据的类型
//accept方法的形参s:依次表示流里面的每一个数据
//方法体:对每一个数据的处理操作(打印)
/*list.stream().forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });*/

list.stream().forEach(s -> System.out.println(s));

ilustrar:

imagen-20230425160329430

20.5.2recuento()

ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰", "张翠山", "张良", "王二麻子", "谢广坤");
long count = list.stream().count();
System.out.println(count);

ilustrar:

El valor de retorno del método .count() es de tipo int, por lo que una vez completada la llamada, el Stream finalizará.

20.5.3toArray()

Object[] arr1 = list.stream().toArray();
System.out.println(Arrays.toString(arr1));

//IntFunction的泛型:具体类型的数组
//apply的形参:流中数据的个数,要跟数组的长度保持一致
//apply的返回值:具体类型的数组
//方法体:就是创建数组
// toArray()                               收集流中的数据,放到数组中
Object[] arr1 = list.stream().toArray();
System.out.println(Arrays.toString(arr1));

	/* String[] arr = list.stream().toArray(new IntFunction<String[]>() {
            @Override
            public String[] apply(int value) {
                return new String[value];
            }
        });

        System.out.println(Arrays.toString(arr));*/

String[] arr2 = list.stream().toArray(value -> new String[value]);
System.out.println(Arrays.toString(arr2));

ilustrar:

  • El papel de los parámetros del método toArray: responsable de crear una matriz del tipo especificado
  • La capa inferior del método toArray obtendrá cada dato de la secuencia por turno y los colocará en la matriz.
  • El valor de retorno del método toArray: es una matriz que contiene todos los datos de la secuencia

detalle:

  • Pregunta: String[] arr2, una matriz de cadenas, imprime el valor de la dirección.
  • Motivo: para imprimir objetos de tipo referencia en Java, el método toString() en Java se utilizará de forma predeterminada y el método toString() se imprimirá como un valor de dirección.
  • Solución: puede reescribir el método toString () en este momento o usar el método toString en la clase de herramienta Arrays.
  • Suplemento: el método Arrays.toString nos ayudará a reescribir el método toString en Java

20.5.4recopilar()

ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌-男-15", "周芷若-女-14", "赵敏-女-13", "张强-男-20",
                   "张三丰-男-100", "张翠山-男-40", "张良-男-35", "王二麻子-男-37", "谢广坤-男-41");

Map<String, Integer> map = list.stream()
    .filter(s -> "男".equals(s.split("-")[1]))
    .collect(Collectors.toMap(
        new Function<String, String>() {
    
    
            @Override
            public String apply(String s) {
    
    
                return s.split("-")[0];
            }
        },
        new Function<String, Integer>() {
    
    
            @Override
            public Integer apply(String s) {
    
    
                return Integer.valueOf(s.split("-")[2]);
            }
        }
    ));
// 或者
Map<String, Integer> map2 = list.stream()
    .filter(s -> "男".equals(s.split("-")[1]))
    .collect(Collectors.toMap(
        s -> s.split("-")[0],
        s -> Integer.parseInt(s.split("-")[2])));
System.out.println(map);// {张强=20, 张良=35, 张翠山=40, 王二麻子=37, 张三丰=100, 张无忌=15, 谢广坤=41}

ilustrar:

El método de recopilación coopera con la clase de herramienta Collectors.toList o Collectors.toSet o Collectors.toMap para completar la adquisición de datos de la secuencia Stream.

21.Referencia del método

Resumen de notas:

  1. Descripción general:

    1. Significado: tome el método existente y utilícelo como el cuerpo del método abstracto en la interfaz funcional.

    2. regla:

      • La referencia debe ser una interfaz funcional.
      • El método al que se hace referencia ya debe existir.
      • Los parámetros formales y el valor de retorno del método al que se hace referencia deben ser coherentes con el método abstracto .
      • La función del método referenciado debe satisfacer las necesidades actuales.
    3. Cita: ::(dos dos puntos consecutivos)

  2. Función: la referencia del método puede hacer que el código sea más conciso y fácil de entender, y mejorar la legibilidad y el mantenimiento del código. Se evitan llamadas repetidas innecesarias en expresiones Lambda .

  3. Clasificación:

    • Para hacer referencia a un método estático :

      /*格式:
      	类::方法名*/
      list.stream().map(Integer::parseInt).forEach(s-> System.out.println(s));
      
    • Métodos de miembros de referencia :

      • Otras categorias

        /* 格式:
        	new对象::方法名*/
        list.stream().filter(new stringOpration()::stringJudge)
        
      • Esta categoría

        /* 格式:
        	本类:this ::方法名 */
        list.stream().filter(this::stringJudge)
        

        Detalles: si este método se usa en un método estático, se requiere un nuevo objeto, porque no existe esto en un método estático

      • clase de padres

        /* 格式:
        	父类:super::方法名*/
        list.stream().filter(super::stringJudge)
        

        Detalles: No hay superpalabra clave en la referencia del método

    • Constructor de referencia :

      /*格式:
      	类名::new */
      List<Student> newList2 = list.stream().map(Student::new)
      
    • El nombre de la clase se refiere al método miembro :

      /*格式:
      	类名::成员方法 */
      list.stream().map(String::toUpperCase)
      

      Nota: diferencia con el método del miembro de referencia

      • Uno es la referencia del objeto , que puede utilizar todos los métodos de la clase ;
      • A esto se hace referencia mediante el nombre de la clase y sus parámetros deben corresponder al primer tipo de parámetro en el método abstracto.
    • Constructor de matriz de referencia :

      /*格式:
      	数据类型[]::new */
      list.stream().toArray(Integer[]::new);
      

21.1 Descripción general

21.1.1 Definición

En Java, una referencia de método es una expresión Lambda especial que se utiliza para simplificar la escritura de expresiones Lambda, especialmente cuando la expresión Lambda solo llama a un método existente.

21.1.2 Reglas

  • La referencia debe ser una interfaz funcional.
  • El método al que se hace referencia ya debe existir.
  • Los parámetros formales y el valor de retorno del método al que se hace referencia deben ser coherentes con el método abstracto.
  • La función del método referenciado debe satisfacer las necesidades actuales.

21.1.3 Caracteres de referencia del método

: : Este símbolo es un operador de referencia y la expresión en la que se encuentra se denomina referencia de método.
: medio:
  • referencia del método

Código de muestra:

class JavaMainApplicationTests {
    
    
    public static int subtraction(int num1, int num2) {
    
    
        return num2 - num1;
    }

    @Test
    void contextLoads() {
    
    
        //需求:创建一个数组,进行倒序排列
        Integer[] arr = {
    
    3, 5, 4, 1, 6, 2};
        //方式一:匿名内部类

        /* Arrays.sort(arr, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });*/


        //方式二:lambda表达式
        //因为第二个参数的类型Comparator是一个函数式接口
        /* Arrays.sort(arr, (Integer o1, Integer o2)->{
            return o2 - o1;
        });*/

        //方式三:lambda表达式简化格式
        //Arrays.sort(arr, (o1, o2)->o2 - o1 );


        //方式四:方法引用
        //1.引用处需要是函数式接口
        //2.被引用的方法需要已经存在
        //3.被引用方法的形参和返回值需要跟抽象方法的形参和返回值保持一致
        //4.被引用方法的功能需要满足当前的要求

        //表示引用FunctionDemo1类里面的subtraction方法
        //把这个方法当做抽象方法的方法体
        Arrays.sort(arr, JavaMainApplicationTests::subtraction);

        System.out.println(Arrays.toString(arr));
    }
}

21.1.4 Clasificación

  1. Método estático de referencia
  2. Método de miembro de referencia
  3. constructor de referencia
  4. El nombre de la clase se refiere al método miembro.
  5. Constructor de matriz de referencia

21.2 Función

Utiliza el método como un objeto en lugar de definir directamente un método anónimo como una expresión Lambda.

Las referencias a métodos pueden hacer que el código sea más conciso y fácil de entender, y mejorar la legibilidad y mantenibilidad del código. Además, las referencias a métodos también se pueden utilizar para mejorar el rendimiento de su código porque evita llamadas repetidas innecesarias en expresiones lambda .

imagen-20230812092547466

ilustrar:

Aquí está la diferencia entre las referencias de métodos.

21.3 Métodos estáticos de referencia

Formato:

::方法名

Ejemplo:

//1.创建集合并添加元素
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"1","2","3","4","5");

//2.把他们都变成int类型
/* list.stream().map(new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                int i = Integer.parseInt(s);
                return i;
            }
        }).forEach(s -> System.out.println(s));*/



//1.方法需要已经存在
//2.方法的形参和返回值需要跟抽象方法的形参和返回值保持一致
//3.方法的功能需要把形参的字符串转换成整数

list.stream()
    .map(Integer::parseInt)
    .forEach(s-> System.out.println(s));

ilustrar:

Cuando los parámetros del método requeridos ya existen, puede llamarlos según el "nombre de clase :: nombre del método"

21.4 Métodos de miembros de referencia

Formato:

对象::成员方法
1.其他类:
	对象::方法名
2.本类:
	this ::方法名 
3.父类:
	super::方法名

Ejemplo (otras clases):

/* 格式:
	其他类:其他类对象::方法名*/
public static void main(String[] args) {
    
    
    //1.创建集合
    ArrayList<String> list = new ArrayList<>();
    //2.添加数据
    Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰");
    //3.其他类:
    list.stream().filter(new stringOpration()::stringJudge)
        .forEach(s-> System.out.println(s));
}
class stringOpration {
    
    
public boolean stringJudge(String s){
    
    
        return s.startsWith("张") && s.length() == 3;
    }
}

ilustrar:

Llamar llamando al nombre del método de otros objetos de clase.

Ejemplo (esta categoría):

/* 格式:
	本类:this ::方法名*/
public class FunctionDemo3  {
    
    
    public static void main(String[] args) {
    
    
        //1.创建集合
        ArrayList<String> list = new ArrayList<>();
        //2.添加数据
        Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰");
        //3.本类,静态方法中是没有this的
        list.stream().filter(new FunctionDemo3()::stringJudge)
                .forEach(s-> System.out.println(s));
    }

    public boolean stringJudge(String s){
    
    
        return s.startsWith("张") && s.length() == 3;
    }
}

detalle:

En el método estático, no existe esto, por lo que es necesario llamar al nuevo objeto de esta clase.

Ejemplo (clase principal):

/* 格式:
	父类:super::方法名*/
public class FunctionDemo3  {
    
    
    public static void main(String[] args) {
    
    
        //1.创建集合
        ArrayList<String> list = new ArrayList<>();
        //2.添加数据
        Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰");
        //3.本类,静态方法中是没有this的
        list.stream().filter(super::stringJudge)
                .forEach(s-> System.out.println(s));
    }
}

ilustrar:

Si esta clase FunctionDemo3 tiene una clase principal, se puede llamar a través del nombre del supermétodo.

21.5 Constructor de referencia

/*格式:
	类名::new */
//1.创建集合对象
ArrayList<String> list = new ArrayList<>();
//2.添加数据
Collections.addAll(list, "张无忌,15", "周芷若,14", "赵敏,13", "张强,20", "张三丰,100", "张翠山,40", "张良,35", "王二麻子,37", "谢广坤,41");
//3.封装成Student对象并收集到List集合中
//String --> Student
/*  List<Student> newList = list.stream().map(new Function<String, Student>() {
            @Override
            public Student apply(String s) {
                String[] arr = s.split(",");
                String name = arr[0];
                int age = Integer.parseInt(arr[1]);
                return new Student(name, age);
            }
        }).collect(Collectors.toList());
        System.out.println(newList);*/


List<Student> newList2 = list.stream().map(Student::new).collect(Collectors.toList());
System.out.println(newList2);

ilustrar:

En este momento, al ejecutar new a través del nombre de la clase Student, se puede llamar al constructor del Student.

public class Student {
    
    
    private String name;
    private int age;


    public Student(String str) {
    
    
        String[] arr = str.split(",");
        this.name = arr[0];
        this.age = Integer.parseInt(arr[1]);
    }
}

ilustrar:

En este momento, los parámetros formales y los valores de retorno en el objeto de la clase Estudiante deben ser consistentes con el método abstracto.

meollo de la cuestión:

En este momento, el valor de retorno del método constructor de forma predeterminada es devolver todo el objeto de la clase Estudiante.

21.6 El nombre de la clase se refiere al método miembro

/*格式:
	类名::成员方法 */
public static void main(String[] args) {
    
    
    /*

        方法引用的规则:
        1.需要有函数式接口
        2.被引用的方法必须已经存在
        3.被引用方法的形参,需要跟抽象方法的第二个形参到最后一个形参保持一致,返回值需要保持一致。
        4.被引用方法的功能需要满足当前的需求

        抽象方法形参的详解:
        第一个参数:表示被引用方法的调用者,决定了可以引用哪些类中的方法
                    在Stream流当中,第一个参数一般都表示流里面的每一个数据。
                    假设流里面的数据是字符串,那么使用这种方式进行方法引用,只能引用String这个类中的方法

        第二个参数到最后一个参数:跟被引用方法的形参保持一致,如果没有第二个参数,说明被引用的方法需要是无参的成员方法

        局限性:
            不能引用所有类中的成员方法。
            是跟抽象方法的第一个参数有关,这个参数是什么类型的,那么就只能引用这个类中的方法。

       */

    //1.创建集合对象
    ArrayList<String> list = new ArrayList<>();
    //2.添加数据
    Collections.addAll(list, "aaa", "bbb", "ccc", "ddd");
    //3.变成大写后进行输出
    //map(String::toUpperCase)
    //拿着流里面的每一个数据,去调用String类中的toUpperCase方法,方法的返回值就是转换之后的结果。
    list.stream().map(String::toUpperCase).forEach(s -> System.out.println(s));


    //String --> String
    /* list.stream().map(new Function<String, String>() {
            @Override
            public String apply(String s) {
                return s.toUpperCase();
            }
        }).forEach(s -> System.out.println(s));*/
}

Nota: diferencia con el método del miembro de referencia

No se puede hacer referencia a todos los métodos miembros de la clase.Si el primer parámetro del método abstracto es de tipo A, solo se puede hacer referencia a los métodos de la clase A.

21.7Método constructor de matriz de referencia

/*格式:
	数据类型[]::new */
 public static void main(String[] args) {
    
    
        /*
        细节:
            数组的类型,需要跟流中数据的类型保持一致。
       */

        //1.创建集合并添加元素
        ArrayList<Integer> list = new ArrayList<>();
        Collections.addAll(list, 1, 2, 3, 4, 5);
        //2.收集到数组当中

        Integer[] arr2 = list.stream().toArray(Integer[]::new);
        System.out.println(Arrays.toString(arr2));

        /*Integer[] arr = list.stream().toArray(new IntFunction<Integer[]>() {
            @Override
            public Integer[] apply(int value) {
                return new Integer[value];
            }
        });*/
     
        //3.打印
    }

22.Manejo de excepciones

Resumen de notas:

  1. Descripción general

    • Anormal: se refiere a la situación anormal que ocurre durante la ejecución del programa , lo que eventualmente conducirá a la parada anormal de la JVM .
    • Arquitectura inusual

    imagen-20230812093622894

    • Clasificación de anomalías

      1. Excepciones en tiempo de compilación : excepto RuntimeExcpetion y sus subclases, todas las demás son excepciones en tiempo de compilación. Debe procesarse durante la fase de compilación y su función es recordarle al programador.
      2. Excepción de tiempo de ejecución : RuntimeException en sí y todas las subclases son excepciones de tiempo de ejecución. No se informa ningún error durante la fase de compilación, ocurre cuando el programa se está ejecutando.
    • mecanismo anormal

      • Genere el nombre de la excepción, la causa de la excepción y la ubicación donde ocurrió la excepción en la consola .
      • El programa deja de ejecutarse y el código debajo de la excepción no se volverá a ejecutar
  2. efectos anormales

    • Las excepciones son información de referencia clave utilizada para consultar errores.
    • Las excepciones se pueden utilizar como un valor de retorno especial dentro de un método para notificar a la persona que llama sobre el estado de ejecución subyacente .
  3. excepción de captura

    • Formato

      try{
               
               
           编写可能会出现异常的代码
      }catch(异常类型  e){
               
               
           处理异常的代码
           //记录日志/打印异常信息/继续抛出异常
      }
      
  4. Cuatro preguntas del alma

    imagen-20230426111351928

  5. Método de excepción

    imagen-20230426111823569
  6. Lanzar una excepción

    • Declarar excepción lanza palabra clave
    • lanzar excepción lanzar palabra clave
  7. Excepción personalizada:

    • Definir clase de excepción

      // 业务逻辑异常
      public class LoginException extends Exception {
               
               
          /**
           *
           * @param message 表示异常提示
           */
          public LoginException(String message) {
               
               
              super(message);
          }
      }
      //
      //
      

      ilustrar:

      1. El nombre de la excepción termina con Exception
      2. La clase de excepción hereda la excepción
      3. La clase de excepción puede generar métodos de construcción sin parámetros, con parámetros y con parámetros vacíos para una descripción detallada.
  8. Ejecución final: finalmente palabra clave

22.1 Descripción general

22.1.1 Definición

El significado de excepción se refiere a una situación anormal que ocurre durante la ejecución del programa, lo que eventualmente hará que la JVM se detenga anormalmente.

22.1.2 Sistema anormal

El mecanismo de excepción en realidad nos ayuda a encontrar problemas en el programa. La clase raíz de excepción es y hay dos java.lang.Throwablesubclases debajo de ella:java.lang.Errorjava.lang.Exceptionjava.lang.Exception

imagen-20230426102346006

  • Error: representa un error a nivel del sistema (un problema grave), una vez que ocurre un problema en el sistema, Sun encapsulará estos errores en objetos de Error. El error es para uso propio de Sun, no para nosotros, los programadores. Entonces los desarrolladores no tenemos que preocuparnos por eso.
  • Excepción: Se llama excepción y representa un problema que puede ocurrir en el programa. Generalmente usamos Exception y sus subclases para encapsular problemas del programa.
  • Excepciones de tiempo de ejecución: RuntimeException y sus subclases, no aparecerá ningún recordatorio de excepción durante la fase de compilación. Excepciones que ocurren durante el tiempo de ejecución (como la excepción de índice de matriz fuera de límites)
  • Excepción en tiempo de compilación: aparecerán recordatorios de excepción durante la fase de compilación. (Por ejemplo: excepción de análisis de fecha)

22.1.3 Clasificación de anomalías

imagen-20230426103246556

  • Excepción en el tiempo de compilación : excepción marcada. Se verificará durante la compilación, si no se maneja la excepción, la compilación fallará. (como un formato de fecha anormal)
  • Excepción de tiempo de ejecución : excepción de tiempo de ejecución. Durante el tiempo de ejecución, se verifican las excepciones. Durante el tiempo de compilación, el compilador no detecta las excepciones en tiempo de ejecución (no se informan errores). (como anomalías matemáticas)

22.1.5 Mecanismo de manejo de excepciones

La forma predeterminada en que la JVM maneja las excepciones

  1. Genere el nombre de la excepción, la causa de la excepción y la ubicación donde ocurrió la excepción en la consola .
  2. El programa deja de ejecutarse y el código debajo de la excepción no se volverá a ejecutar

Ejemplo:

System.out.println("狂踹瘸子那条好腿");
System.out.println(2/0);//算术异常 ArithmeticException
System.out.println("是秃子终会发光");
System.out.println("火鸡味锅巴");

Efecto de impresión:imagen-20230426105516747

22.2 Función

efecto:

  • Las excepciones son información de referencia clave utilizada para consultar errores.

    imagen-20230426104428716

  • Las excepciones se pueden utilizar como un valor de retorno especial dentro de un método para informar a la persona que llama sobre la ejecución subyacente.

    imagen-20230426104523278

    ilustrar:

En pocas palabras, lanza una excepción.

22.3 Captura de excepciones

El método try-catch consiste en detectar excepciones.

ilustrar:

  • **intenta:** El código que puede generar excepciones está escrito en este bloque de código.
  • **catch:** se utiliza para capturar algún tipo de excepción y realizar el procesamiento de la excepción detectada.
  • Captura de excepciones : Java captura declaraciones específicas de excepciones y puede manejar excepciones de maneras específicas.

Aviso:

​ Ni try ni catch se pueden usar solos, deben usarse juntos.

Caso de uso básico

/* 格式:
try{
     编写可能会出现异常的代码
}catch(异常类型  e){
     处理异常的代码
     //记录日志/打印异常信息/继续抛出异常
} */

int[] arr = {
    
    1, 2, 3, 4, 5, 6};
try{
    
    
    //可能出现异常的代码;
    System.out.println(arr[10]);//此处出现了异常,程序就会在这里创建一个ArrayIndexOutOfBoundsException对象
    //new ArrayIndexOutOfBoundsException();
    //拿着这个对象到catch的小括号中对比,看括号中的变量是否可以接收这个对象
    //如果能被接收,就表示该异常就被捕获(抓住),执行catch里面对应的代码
    //当catch里面所有的代码执行完毕,继续执行try...catch体系下面的其他代码
}catch(ArrayIndexOutOfBoundsException e){
    
    
    //如果出现了ArrayIndexOutOfBoundsException异常,我该如何处理
    System.out.println("索引越界了");
}

System.out.println("看看我执行了吗?");

22.4 Preguntas frecuentes sobre el manejo de excepciones

imagen-20230426111351928

  1. Si no se encuentra ningún problema al intentarlo, ¿cómo ejecutarlo?

    • Se ejecutarán todos los códigos en try y el código en catch no se ejecutará.

       int[] arr = {
              
              1, 2, 3, 4, 5, 6};
      
              try{
              
              
                  System.out.println(arr[0]);//1
              }catch(ArrayIndexOutOfBoundsException e){
              
              
                  System.out.println("索引越界了");
              }
      
              System.out.println("看看我执行了吗?");//看看我执行了吗?
      
  2. Si se pueden encontrar varios problemas al intentar, ¿cómo ejecutarlos?

    • Escribirá múltiples capturas correspondientes a ellas.

      //JDK7
      int[] arr = {
              
              1, 2, 3, 4, 5, 6};
      
      try{
              
              
          System.out.println(arr[10]);//ArrayIndexOutOfBoundsException
          System.out.println(2/0);//ArithmeticException,报错则跳过此句
          String s = null;
          System.out.println(s.equals("abc"));
      }catch(ArrayIndexOutOfBoundsException | ArithmeticException e){
              
              
          System.out.println("索引越界了");
      }catch(NullPointerException e){
              
              
          System.out.println("空指针异常");
      }catch (Exception e){
              
              
          System.out.println("Exception");
      }
      
      System.out.println("看看我执行了吗?");
      

      detalle:

      Si queremos detectar múltiples excepciones, si existe una relación padre-hijo entre estas excepciones, entonces la clase principal debe escribirse a continuación

      Reponer:

      Después de JDK7, podemos detectar múltiples excepciones al mismo tiempo en catch, separadas por |

  3. Si el problema encontrado en el intento no se detecta, ¿cómo ejecutarlo?

    • El código equivalente a try...catch está escrito para nada y eventualmente se entregará a la máquina virtual para su procesamiento.

      int[] arr = {
              
              1, 2, 3, 4, 5, 6};
      
      try{
              
              
          System.out.println(arr[10]);//new ArrayIndexOutOfBoundsException();
      }catch(NullPointerException e){
              
              
          System.out.println("空指针异常");
      }
      
      System.out.println("看看我执行了吗?");
      
      
  4. Si se encuentra un problema en el intento, ¿se seguirán ejecutando otros códigos a continuación?

    • El siguiente código no se ejecutará, saltará directamente al catch correspondiente y ejecutará el cuerpo de la declaración en el catch. Pero si no hay una captura correspondiente que coincida, aún así se entregará a la máquina virtual para su procesamiento.

      int[] arr = {
              
              1, 2, 3, 4, 5, 6};
      
      try{
              
              
          System.out.println(arr[10]);
          System.out.println("看看我执行了吗?... try");
      }catch(ArrayIndexOutOfBoundsException e){
              
              
          System.out.println("索引越界了");
      }
      
      System.out.println("看看我执行了吗?... 其他代码");
      

22.5 Métodos comúnmente utilizados para excepciones

imagen-20230426111823569

22.5.1obtener mensaje()

// 返回此throwable的详细消息字符串
int[] arr = {
    
    1, 2, 3, 4, 5, 6};
try {
    
    
    System.out.println(arr[10]);
} catch (ArrayIndexOutOfBoundsException e) {
    
    
    String message = e.getMessage();
    System.out.println(message);//Index 10 out of bounds for length 6 
}

22.5.2acadena()

// 返回此可抛出的简短描述
int[] arr = {
    
    1, 2, 3, 4, 5, 6};
try {
    
    
    System.out.println(arr[10]);
} catch (ArrayIndexOutOfBoundsException e) {
    
    
    String str = e.toString();
    System.out.println(str);//java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 6
}

22.5.3imprimirStackTrace()

// 把异常的错误信息输出在控制台
int[] arr = {
    
    1, 2, 3, 4, 5, 6};
try {
    
    
    System.out.println(arr[10]);
} catch (ArrayIndexOutOfBoundsException e) {
    
    
    e.printStackTrace();
}

imagen-20230426141848634

22.6 Manejo de lanzamiento de excepciones

Manejo de excepciones:

  • Lanzamientos de excepciones en tiempo de compilación
  • Lanzamiento de excepción en tiempo de ejecución

22.6.1 Declaración de palabras clave de lanzamiento de excepción

Aviso:

Escrito en la definición del método, significa declarar una excepción y decirle a la persona que llama qué excepciones pueden ocurrir al usar este método.

Formato:

public void 方法() throws 异常类名1,异常类名2...{
    
    
	……
}

22.6.2 Lanzar palabra clave de lanzamiento de excepción

Aviso:

Escríbalo en el método, finalice el método, arroje manualmente el objeto de excepción y entréguelo a la persona que llama. El siguiente código en el método ya no se ejecutará.

Formato:

public void方法(){
    
    
    throw new Nul1PointerException();
}
// 例如
if(arr == null){
    
    
    //手动创建一个异常对象,并把这个异常交给方法的调用者处理
    //此时方法就会结束,下面的代码不会再执行了
    throw new NullPointerException();
}

22.7 Excepciones personalizadas

22.7.1 Descripción general

Significado: defina clases de excepción de acuerdo con las situaciones anormales de su propio negocio durante el desarrollo.

22.7.2 Pasos de uso

1. Definir clase de excepción

// 业务逻辑异常
public class LoginException  {
    
    
 
}

ilustrar:

Por lo general, el nombre de la clase se llama xxxException y termina con Exception. Al mismo tiempo, el nombre de la clase se entiende mejor por su nombre.

2. Escribir relación de herencia

// 业务逻辑异常
public class LoginException extends Exception {
    
    
 
}

ilustrar:

Si esta excepción personalizada se utiliza como excepción en tiempo de compilación, hereda la excepción

Si esta excepción personalizada se usa para excepciones en tiempo de ejecución, hereda RuntimeException

3. Construcción de parámetros vacíos

// 业务逻辑异常
public class LoginException extends Exception {
    
    
    /**
     * 空参构造
     */
    public LoginException() {
    
    
    }
}

ilustrar:

Por lo general, se implementan métodos de construcción de parámetros vacíos y construcción parametrizada.

4.Construcción con parámetros.

// 业务逻辑异常
public class LoginException extends Exception {
    
    
    /**
     *
     * @param message 表示异常提示
     */
    public LoginException(String message) {
    
    
        super(message);
    }
}
}

ilustrar:

El propósito de construir con parámetros es describir mejor el mensaje de error.

22.8 Ejecución final

En Java, finalmente es una palabra clave que se utiliza para definir el código que debe ejecutarse en un bloque de código try-catch. Independientemente de si se lanza una excepción en el bloque try, se ejecutará el bloque finalmente.

Formato:

try{
    
    
     编写可能会出现异常的代码
}catch(异常类型  e){
    
    
     处理异常的代码
     //记录日志/打印异常信息/继续抛出异常
}finally{
    
    
	无论如何都会执行的代码
}

detalle

Cuando el método relevante para salir de la JVM se llama solo en try o catch, finalmente no se ejecutará; de lo contrario, finalmente siempre se ejecutará.

Ejemplo

try {
    
    
    read("a.txt");
} catch (FileNotFoundException e) {
    
    
    //抓取到的是编译期异常  抛出去的是运行期 
    throw new RuntimeException(e);
} finally {
    
    
    System.out.println("不管程序怎样,这里都将会被执行。");
}

23.Clase de archivo

Resumen de notas:

  1. Descripción general:

    1. Significado: java.io.Filelas clases son representaciones abstractas de nombres de rutas de archivos y directorios.
    2. Ruta: ruta absoluta y ruta relativa
  2. Función: se utiliza para operar archivos y directorios, como crear , eliminar y obtener información de archivos. Tenga en cuenta que la clase Archivo no puede obtener el contenido detallado del archivo .

  3. Método de construcción:

    imagen-20230426155428093
  4. Métodos de miembros comunes

    1. Juicio y adquisición: isDirectory (), isFIle (), existe (), length (), getAbsolutePath (), getPath (), getName (), lastModified ()
    2. Crear, eliminar: createNewFile (), mkdir (), mkdirs (), eliminar ()
    3. Obtener y recorrer: ListFiles () (énfasis)

23.1 Descripción general

23.1.1 Definición

La clasejava.io.File es una representación abstracta de nombres de rutas de archivos y directorios, que se utiliza principalmente para operaciones como la creación, búsqueda y eliminación de archivos y directorios.

23.1.2 Ruta

imagen-20230426155057941

23.2 Función

La clase Archivo en Java es una clase utilizada para representar archivos o directorios . Se puede utilizar para operar archivos o directorios , como crear, leer, escribir, eliminar y otras operaciones.

La clase Archivo es parte de la biblioteca Java I/O. Proporciona una variedad de métodos para obtener información sobre archivos y directorios, como nombre de archivo, ruta, tamaño, hora de modificación, etc.

La clase File también se puede utilizar para recorrer archivos y directorios, así como para filtrar archivos y directorios. Es una de las clases comúnmente utilizadas en programas Java.

23.3 Métodos de construcción

imagen-20230426155428093

Ejemplo:

// 文件路径名
String pathname = "D:\\aaa.txt";
File file1 = new File(pathname); 

// 文件路径名
String pathname2 = "D:\\aaa\\bbb.txt";
File file2 = new File(pathname2); 

// 通过父路径和子路径字符串
 String parent = "d:\\aaa";
 String child = "bbb.txt";
 File file3 = new File(parent, child);

// 通过父级File对象和子路径字符串
File parentDir = new File("d:\\aaa");
String child = "bbb.txt";
File file4 = new File(parentDir, child);

consejos:

  1. Un objeto Archivo representa un archivo o directorio que realmente existe en el disco duro.
  2. Independientemente de si hay un archivo o directorio en la ruta, no afecta la creación del objeto Archivo.

23.4 Métodos de miembros comunes

23.4.1 Sentencia y adquisición

imagen-20230426160104422

Ejemplo:

23.4.1.1isDirectory()、isFIle()、existe()

//1.对一个文件的路径进行判断
File f1 = new File("D:\\aaa\\a.txt");
System.out.println(f1.isDirectory());//false
System.out.println(f1.isFile());//true
System.out.println(f1.exists());//true
System.out.println("--------------------------------------");
//2.对一个文件夹的路径进行判断
File f2 = new File("D:\\aaa\\bbb");
System.out.println(f2.isDirectory());//true
System.out.println(f2.isFile());//false
System.out.println(f2.exists());//true
System.out.println("--------------------------------------");
//3.对一个不存在的路径进行判断
File f3 = new File("D:\\aaa\\c.txt");
System.out.println(f3.isDirectory());//false
System.out.println(f3.isFile());//false
System.out.println(f3.exists());//false

23.4.1.2longitud()

File f1 = new File("D:\\aaa\\a.txt");
long len = f1.length();
System.out.println(len);

File f2 = new File("D:\\aaa\\bbb");
long len2 = f2.length();
System.out.println(len2);

detalle:

  • Este método sólo puede obtener el tamaño del archivo , en bytes. Si nuestra unidad es M o G, podemos seguir dividiendo entre 1024
  • Este método no puede obtener el tamaño de la carpeta. Si queremos obtener el tamaño de una carpeta, debemos sumar los tamaños de todos los archivos de la carpeta.

23.4.1.3obtenerRutaAbsoluta()

File f3 = new File("D:\\aaa\\a.txt");
String path1 = f3.getAbsolutePath();
System.out.println(path1);

File f4 = new File("myFile\\a.txt");
String path2 = f4.getAbsolutePath();
System.out.println(path2);

23.4.1.4getPath()

File f5 = new File("D:\\aaa\\a.txt");
String path3 = f5.getPath();
System.out.println(path3);//D:\aaa\a.txt

File f6 = new File("myFile\\a.txt");
String path4 = f6.getPath();
System.out.println(path4);//myFile\a.txt

23.4.1.5obtenerNombre()

File f7 = new File("D:\\aaa\\a.txt");
String name1 = f7.getName();
System.out.println(name1);//a/txt

File f8 = new File("D:\\aaa\\bbb");
String name2 = f8.getName();
System.out.println(name2);//bbb

detalle:

  • Cuando este método obtiene el nombre del archivo
  • Cuando este método obtiene el nombre de la carpeta

23.4.1.6última modificación()

File f9 = new File("D:\\aaa\\a.txt");
long time = f9.lastModified();
System.out.println(time); //1667380952425

23.4.2Crear, eliminar

imagen-20230426163941377

Aviso:

El método de eliminación solo puede eliminar archivos y carpetas vacías de forma predeterminada, y el método de eliminación elimina archivos directamente sin tener que ir a la papelera de reciclaje.

23.4.2.1crearNuevoArchivo()

boolean b = f1.createNewFile();
System.out.println(b);//true

detalle:

  • Crear un archivo
    • Si el archivo representado por la ruta actual no existe, la creación es exitosa y el método devuelve verdadero
    • Si el archivo representado por la ruta actual existe, la creación falla y el método devuelve falso.
  • Si la ruta principal no existe, el método tendrá una excepción IOException
  • El método createNewFile debe crear un archivo. Si la ruta no contiene un nombre de sufijo, se creará un archivo sin sufijo.

23.4.2.2mkdir()

File f2 = new File("D:\\aaa\\aaa\\bbb\\ccc");
boolean b = f2.mkdir();
System.out.println(b);

detalle:

  • La ruta es única en Windows. Si la ruta actual ya existe, la creación falla y se devuelve falso.
  • El método mkdir solo puede crear carpetas de un solo nivel y no puede crear carpetas de varios niveles.

23.4.2.3mkdirs()

File f3 = new File("D:\\aaa\\ggg");
boolean b = f3.mkdirs();
System.out.println(b);//true

detalle:

  • Puede crear carpetas de un solo nivel y de varios niveles.

23.4.2.4eliminar()

//1.创建File对象
File f1 = new File("D:\\aaa\\eee");
//2.删除
boolean b = f1.delete();
System.out.println(b);

detalle:

  • Si eliminas un archivo, elimínalo directamente sin ir a la Papelera de reciclaje.
  • Si eliminas una carpeta
    1. Si la carpeta está vacía, elimínela directamente sin ir a la Papelera de reciclaje.
    2. La eliminación falla si la carpeta tiene contenido

23.4.3 Obtener y atravesar

imagen-20230426212031932

23.4.3.1listaRaíces()

File[] arr = File.listRoots();
System.out.println(Arrays.toString(arr));

23.4.3.2lista()

File f1 = new File("D:\\aaa");
String[] arr2 = f1.list();
for (String s : arr2) {
    
    
    System.out.println(s);
}

23.4.3.3 lista (filtro de filtro de nombre de archivo)

//3.list(FilenameFilter filter)  利用文件名过滤器获取当前该路径下所有内容
//需求:我现在要获取D:\\aaa文件夹里面所有的txt文件
File f2 = new File("D:\\aaa");
//accept方法的形参,依次表示aaa文件夹里面每一个文件或者文件夹的路径
//参数一:父级路径
//参数二:子级路径
//返回值:如果返回值为true,就表示当前路径保留
//        如果返回值为false,就表示当前路径舍弃不要
String[] arr3 = f2.list(new FilenameFilter() {
    
    
    @Override
    public boolean accept(File dir, String name) {
    
    
        File src = new File(dir,name);
        return src.isFile() && name.endsWith(".txt");
    }
});

System.out.println(Arrays.toString(arr3));

23.4.3.4listFiles() (maestro)

//1.创建File对象
File f = new File("D:\\aaa");
//2.需求:打印里面所有的txt文件
File[] arr = f.listFiles();
for (File file : arr) {
    
    
    //file依次表示aaa文件夹里面每一个文件或者文件夹的路径
    if(file.isFile() && file.getName().endsWith(".txt")){
    
    
        System.out.println(file);
    }
}

Aviso:

  • Cuando la ruta indicada por el archivo que llama no existe, devuelve nulo
  • Cuando la ruta indicada por el archivo que llama es un archivo, devuelve nulo
  • Cuando la ruta representada por el archivo de la persona que llama es una carpeta vacía, se devuelve una matriz de longitud 0.
  • Cuando la ruta representada por el archivo de la persona que llama es una carpeta con contenido, las rutas de todos los archivos y carpetas que contiene se colocan en la matriz de archivos y se devuelven.
  • Cuando la ruta indicada por la persona que llama Archivo es una carpeta con archivos ocultos, coloque las rutas de todos los archivos y carpetas en la matriz Archivo y regrese, incluidos los archivos ocultos. Cuando la ruta indicada por la persona que llama Archivo es un archivo que requiere permiso para acceder Al recortar, devuelve nulo

23.4.3.6listFiles(filtro FileFilter)

//创建File对象
File f = new File("D:\\aaa");
//调用listFiles(FileFilter filter)
File[] arr1 = f.listFiles(new FileFilter() {
    
    
    @Override
    public boolean accept(File pathname) {
    
    
        return pathname.isFile() && pathname.getName().endsWith(".txt");
    }
});

23.4.3.5listFiles(filtro de filtro de nombre de archivo)

//调用listFiles(FilenameFilter filter)
File[] arr2 = f.listFiles(new FilenameFilter() {
    
    
    @Override
    public boolean accept(File dir, String name) {
    
    
        File src = new File(dir, name);
        return src.isFile() && name.endsWith(".txt");
    }
});
System.out.println(Arrays.toString(arr2));

24. Flujo IO

Resumen de notas: ver cada sección

24.1 Descripción general

Resumen de notas:

  1. Definición: IO se refiere a operaciones de entrada y salida en archivos

  2. Clasificación:

    • Flujo de entrada, flujo de salida: lectura de datos y escritura de datos
    • Flujo de bytes, flujo de caracteres: cualquier archivo binario y caracteres de procesamiento . La transmisión subyacente son siempre datos binarios.

    imagen-20230812095212381

  3. Arquitectura de transmisión:

    imagen-20230812095223902

  4. Utilice el principio de flujo IO: cree mientras usa

24.1.1 Definición

Las operaciones de E/S en Java se refieren principalmente al uso java.iodel contenido del paquete para realizar operaciones de entrada y salida. La entrada también se denomina lectura de datos y la salida también se denomina escritura de datos.

​ El flujo IO en Java se refiere a un conjunto de clases e interfaces para procesar operaciones de entrada y salida, lo que permite a los programas leer y escribir datos e interactuar con archivos, redes y otros dispositivos.

24.1.2 Clasificación

imagen-20230427075443583

24.1.3 Flujo de entrada y flujo de salida

  • Flujo de entrada:

    En los flujos IO en Java, el flujo de entrada es el flujo utilizado para leer datos . Los flujos de entrada pueden leer datos de diversas fuentes de datos, como archivos, conexiones de red y entradas estándar.

    imagen-20230427141537602

  • Flujo de salida:

    En el flujo IO de Java, el flujo de salida se refiere al flujo que escribe datos desde el programa al exterior . Los flujos de salida se utilizan generalmente para escribir datos en el programa en archivos, conexiones de red, tuberías, etc.imagen-20230427141749753

24.1.4 Flujo de bytes y flujo de caracteres

  • flujo de bytes

    Todos los datos de archivos (texto, imágenes, videos, etc.) se almacenan en forma de números binarios , un byte a la vez, y lo mismo ocurre con la transmisión. Por lo tanto, los flujos de bytes pueden transmitir datos de archivos arbitrarios . Al operar flujos, siempre debemos tener claro que no importa qué objeto de flujo se utilice, la transmisión subyacente siempre son datos binarios .

    imagen-20230427142208211

  • flujo de personajes

    En el flujo IO en Java, un flujo de caracteres es un flujo IO que procesa datos de caracteres, es decir, un flujo que lee o escribe datos por carácter. A diferencia de los flujos de bytes, los flujos de caracteres se procesan según caracteres (códigos Unicode)

    imagen-20230427142233684

24.1.5 Sistema de flujo

imagen-20230504084825259

Flujo elemental de 24,2 bytes

Resumen de notas:

  1. Descripción general:

    • Definición: leer datos de flujo de bytes de un archivo

    • Arquitectura:

      imagen-20230812102521292

  2. Método de construcción:

    1. Flujo de entrada:
      • FileInputStream (archivo de archivo)
      • FileInputStream (nombre de cadena)
    2. Flujo de salida:
      • FileOutputStream (archivo de archivo)
      • FileOutputStream (nombre de cadena)
  3. Métodos de miembros comunes:

    1. Flujo de entrada:

      • leer ()
      • leer (byte[] b)
      • cerrar ()
    2. Flujo de salida:

      • escribir (int b)

      • escribir(byte[] b)
      • escribir (byte[] b, int off, int len)

  4. principio:

    1. Crear canal

      FileInputStream fis = new FileInputStream();
      FileOutputStream fos = new FileOutputStream("myio\\a.txt");
      
    2. Procesamiento de datos

      int b1 = fis.read(); // 读数据
      fos.write(97); // 写数据
      
    3. Liberar recursos

      fis.close();
      fos.close();
      

24.2.1 Flujo de entrada-FileIntputStream

24.2.1.1 Descripción general

EsFileInputStream una clase que se utiliza para leer datos de archivos en la biblioteca Java IO y se utiliza para leer datos de flujo de bytes de archivos.

24.2.1.2 Casos de uso básicos

//1.创建对象
FileInputStream fis = new FileInputStream("myio\\a.txt");
//2.读取数据
int b1 = fis.read();
System.out.println((char)b1);
int b2 = fis.read();
System.out.println((char)b2);
int b3 = fis.read();
System.out.println((char)b3);
int b4 = fis.read();
System.out.println((char)b4);
int b5 = fis.read();
System.out.println((char)b5);
int b6 = fis.read();
System.out.println(b6);//-1
//3.释放资源
fis.close();

consejos:

El método read() mueve el puntero cada vez que se lee un dato.

24.2.1.3 Método de construcción

  • FileInputStream(File file): Crea un FileInputStream abriendo una conexión a un archivo real nombrado por el archivo objeto Archivo en el sistema de archivos.
  • FileInputStream(String name): Crea un FileInputStream abriendo una conexión a un archivo real nombrado por la ruta en el sistema de archivos.
24.2.1.3.1FileInputStream (archivo de archivo)
/* 格式:
	public FileInputStream(File file) */
// 使用File对象创建流对象
File file = new File("a.txt");
FileInputStream fos = new FileInputStream(file);

detalle:

Si el archivo no existe, se informará directamente un error. Porque el archivo creado no tiene datos y no tiene significado. Por lo tanto, Java no diseña una lógica tan sin sentido y el archivo no existe e informa directamente un error.

24.2.1.3.2FileInputStream (nombre de cadena)
/* 格式:
	FileInputStream(String name) */
// 使用文件名称创建流对象
FileInputStream fos = new FileInputStream("b.txt");

detalle:

Lo mismo que arriba

24.2.1.4 Métodos de miembros comunes

imagen-20230427150251847

24.2.1.4.1leer()
/* 格式:
	FileInputStream对象.raad() 
   作用:一次读取一个字节数据*/
int b1 = fis.read();

detalle:

  • Lea un byte a la vez y lo que se lee es el número correspondiente a los datos en ASClI.
  • Se ha leído el final del archivo y el método de lectura devuelve -1.
24.2.1.4.2leer(byte[] b)
/* 格式:
	FileInputStream对象.raad(byte[] b)
   作用:一次读取一个字节数组数据 */
byte[] b = new byte[2];
int len= fis.read(b)

consejos:

Al utilizar la lectura de matriz, se leen varios bytes cada vez, lo que reduce la cantidad de operaciones de E/S entre sistemas y mejora así la eficiencia de la lectura y la escritura.

24.2.1.4.3cerrar()
/* 格式:
	FileInputStream对象.close()
   作用:释放资源 */
fis.close();

ilustrar:

Liberar ocupación de recursos

24.2.1.5 Leer varios bytes a la vez

//1.创建对象
FileInputStream fis = new FileInputStream("myio\\a.txt");
//2.读取数据
byte[] bytes = new byte[2];
//一次读取多个字节数据,具体读多少,跟数组的长度有关
//返回值:本次读取到了多少个字节数据
int len1 = fis.read(bytes);
System.out.println(len1);//2
String str1 = new String(bytes,0,len1);
System.out.println(str1);


int len2 = fis.read(bytes);
System.out.println(len2);//2
String str2 = new String(bytes,0,len2);
System.out.println(str2);

int len3 = fis.read(bytes);
System.out.println(len3);// 1
String str3 = new String(bytes,0,len3);
System.out.println(str3);// ed 

//3.释放资源
fis.close();

ilustrar:

imagen-20230427150810725

  • En este momento, cada lectura colocará los bytes leídos del archivo en la matriz de bytes.
  • Cuando se lee el último byte, solo se sobrescribirá el primer número de la matriz en este momento, por lo que los últimos datos leídos permanecerán en los datos.
  • Ahora, a través de una nueva cadena (matriz de flujo de bytes, índice, longitud), este método de construcción de cadenas puede evitar razonablemente este problema de lectura.

24.2.1.6 Lectura de bucle

//1.创建对象
FileInputStream fis = new FileInputStream("myio\\a.txt");
//2.循环读取
int b;
while ((b = fis.read()) != -1) {
    
    
    System.out.println((char) b);
}
//3.释放资源
fis.close();

24.2.1.7 Principio

Cómo funcionan los flujos de entrada

imagen-20230427084525131

ilustrar:

FileInputStream fis = new FileInputStream();

imagen-20230427084537691

ilustrar:

int b1 = fis.read();

imagen-20230427084558787

ilustrar:

fis.close();

24.3.2 Flujo de salida: FileOutputStream

24.3.2.1 Descripción general

EsFileOutputStream una clase del paquete Java I/O, también llamada flujo de salida de bytes. Flujo de salida de bytes utilizado para operar archivos locales. Los datos del programa se pueden escribir en archivos locales.

24.3.2.2 Casos de uso básicos

//1.创建对象
//写出 输出流 OutputStream
//本地文件    File
FileOutputStream fos = new FileOutputStream("myio\\a.txt");
//2.写出数据
fos.write(97);
//3.释放资源
fos.close();

24.3.2.3 Método de construcción

  • public FileOutputStream(File file):Crea una secuencia de salida de archivo para escribir en el archivo representado por el objeto Archivo especificado.
  • public FileOutputStream(String name): Crea una secuencia de salida de archivo para escribir en el archivo con el nombre especificado.
24.3.2.3.1FileOutputStream (archivo de archivo)
/* 格式:
	public FileOutputStream(File file) */
// 使用File对象创建流对象
File file = new File("a.txt");
FileOutputStream fos = new FileOutputStream(file);

detalle:

  • Si el archivo no existe, se creará un archivo nuevo, pero la ruta principal debe existir.
  • Si el archivo ya existe, se borrará.
24.3.2.3.2FileOutputStream(nombre de cadena)
/* 格式:
	public FileOutputStream(File file) 
	作用:使用文件名称创建流对象*/
FileOutputStream fos = new FileOutputStream("b.txt");

24.3.1.4 Métodos de miembros comunes

imagen-20230427081442801

24.3.1.4.1escribir(int b)
/* 格式:
	FileOutputStream对象.write(int b)
	作用:一次写一个字节数据*/
fos.write(97); 

detalle:

El parámetro del método de escritura es un número entero, pero lo que realmente se escribe en el archivo local es el carácter ASCII correspondiente al número entero.

24.3.1.4.2escribir(byte[] b)
/* 格式:
	FileOutputStream对象.write(int b)
	作用:一次写一个字节数组数据*/
byte[] bytes = {
    
    97, 98, 99, 100, 101};
fos.write(bytes);

ilustrar:

Al utilizar la escritura de matriz, se escriben varios bytes cada vez, lo que reduce la cantidad de operaciones de E/S entre sistemas y mejora así la eficiencia de la lectura y la escritura.

24.3.1.4.3escribir(byte[] b, int apagado, int len)
/* 格式:
	FileOutputStream对象.write(byte[] b, int off, int len)
	作用:一次写一个字节数组的部分数据*/
byte[] bytes = {
    
    97, 98, 99, 100, 101};
// 从索引1位开始,写入2为字节数
fos.write(bytes,1,2);// b c
24.3.1.4.4cerrar()
/* 格式:
	FileOutputStream对象.close()
   作用:释放资源 */
fis.close();

ilustrar:

Los recursos deben liberarse después de cada uso de la transmisión.

24.3.1.5 Saltos de línea y continuaciones

//1.创建对象
FileOutputStream fos = new FileOutputStream("myio\\a.txt",true);  //第二个参数为续写开关
//2.写出数据
String str = "kankelaoyezuishuai";
byte[] bytes1 = str.getBytes();
fos.write(bytes1);

//再次写出一个换行符就可以了
String wrap = "\r\n";
byte[] bytes2 = wrap.getBytes();
fos.write(bytes2);

String str2 = "666";
byte[] bytes3 = str2.getBytes();
fos.write(bytes3);

//3.释放资源
fos.close();

consejos:

  1. Escribe en una nueva línea:
    • Simplemente escribe una nueva línea nuevamente.
    • ventanas: \r\n
    • Linux:\n
    • Mac:\r
  2. detalle:
    • En el sistema operativo Windows, Java optimiza el retorno de carro y el avance de línea.
    • Aunque el completo es \r\n, escribimos uno de ellos \r o \n,
    • Java también puede implementar saltos de línea, porque Java los completará bajo el capó.
  3. Continuación:
    • Si desea continuar escribiendo, simplemente active el interruptor para continuar escribiendo.
    • Posición del interruptor: el segundo parámetro del objeto creado.
    • Predeterminado falso: indica que la escritura continua está desactivada. En este momento, al crear un objeto se borrará el archivo.
    • Pasar verdadero manualmente: significa habilitar la escritura continua y la creación de un objeto no borrará el archivo en este momento.

24.3.1.3 Principio

Cómo funcionan los flujos de salida

imagen-20230427080347014

ilustrar:

Generar un canal para transmisión de datos a través del nuevo método

imagen-20230427080419743

ilustrar:

Transmisión de datos mediante método de escritura.

imagen-20230427080505671

ilustrar:

Destruya el canal de transmisión de datos mediante el método de cierre.

24.3.3 Caso – Copia de archivo

//1.创建对象
FileInputStream fis = new FileInputStream("D:\\itheima\\movie.mp4");
FileOutputStream fos = new FileOutputStream("myio\\copy.mp4");
//2.拷贝
//核心思想:边读边写
int b;
while((b = fis.read()) != -1){
    
    
    fos.write(b);
}
//3.释放资源
//规则:先开的最后关闭
fos.close();
fis.close();

consejos:

El principio de cierre del flujo: abrir primero y luego cerrar, y luego abrir y luego cerrar.

Desventajas:

imagen-20230427085941843

ilustrar:

Si se leen archivos grandes, será muy lento.

//1.创建对象
FileInputStream fis = new FileInputStream("D:\\itheima\\movie.mp4");
FileOutputStream fos = new FileOutputStream("myio\\copy.mp4");
//2.拷贝
int len;
byte[] bytes = new byte[1024 * 1024 * 5];
while((len = fis.read(bytes)) != -1){
    
    
    fos.write(bytes,0,len);
}
//3.释放资源
fos.close();
fis.close();

ilustrar:

En este momento, el uso de matrices para lectura y escritura puede reducir la cantidad de operaciones de IO entre sistemas, mejorando así la eficiencia de la lectura y escritura.

24.3 Flujo elemental de caracteres

Resumen de notas:

  1. Descripción general:

    • Significado: leer datos de caracteres de un archivo

    • Arquitectura:

      imagen-20230812102704912

  2. Método de construcción:

    1. Flujo de entrada:

      • FileReader (archivo de archivo)
      • FileReader (nombre de archivo de cadena)
    2. Flujo de salida:

      • FileWriter (archivo de archivo)
      • FileWriter (nombre de ruta de cadena)
  3. Métodos de miembro:

    1. Flujo de entrada:

      • leer()
      • leer(char[] cbuf)
    2. Flujo de salida:

      • escribir (int/cadena c)
      • escribir(char[] cbuf)
      • escribir(char[] cbuf, int off, int len)
      • enjuagar()
  4. Principio: después de que la capa inferior lea los datos, guardará 4 bytes de parte de los datos en el búfer para facilitar la lectura y acelerar la lectura y escritura.

Características:

  • Flujo de entrada: lea un byte a la vez, cuando encuentre chino, lea varios bytes a la vez
  • Flujo de salida: la capa inferior codificará los datos de acuerdo con el método de codificación especificado, los convertirá en bytes y luego los escribirá en el archivo.

Codificación de caracteres: las reglas de correspondencia entre bytes y caracteres. La codificación china predeterminada para los sistemas Windows es la tabla de codificación GBK. La codificación en IDEA tiene como valor predeterminado la tabla de codificación UTF-8.

24.3.1 Flujo de entrada-FileReader

24.3.1.1 Descripción general

EsFileReader una clase del paquete Java I/O que se utiliza para leer datos de caracteres de archivos. Su función es convertir el flujo de entrada de caracteres en un flujo de entrada de bytes y leer los datos de caracteres en el archivo. A menudo se utiliza para leer archivos de texto.

24.3.1.2 Casos de uso básicos

//1.创建对象并关联本地文件
FileReader fr = new FileReader("myio\\a.txt");
//2.读取数据 read()
//字符流的底层也是字节流,默认也是一个字节一个字节的读取的。
//如果遇到中文就会一次读取多个,GBK一次读两个字节,UTF-8一次读三个字节

//read()细节:
//1.read():默认也是一个字节一个字节的读取的,如果遇到中文就会一次读取多个
//2.在读取之后,方法的底层还会进行解码并转成十进制。
//  最终把这个十进制作为返回值
//  这个十进制的数据也表示在字符集上的数字
//  英文:文件里面二进制数据 0110 0001
//          read方法进行读取,解码并转成十进制97
//  中文:文件里面的二进制数据 11100110 10110001 10001001
//          read方法进行读取,解码并转成十进制27721

// 我想看到中文汉字,就是把这些十进制数据,再进行强转就可以了

int ch;
while((ch = fr.read()) != -1){
    
    
    System.out.print((char)ch);
}

//3.释放资源
fr.close();

24.3.1.3 Método de construcción

  • FileReader(File file): Crea un nuevo FileReader, dado un objeto Archivo para leer.
  • FileReader(String fileName): Crea un nuevo FileReader, dado el nombre del archivo que se va a leer.
24.3.1.3.1FileReader(Archivo de archivo)
/* 格式:
	public FileReader(File file) 
	作用:使用File对象创建流对象*/
File file = new File("a.txt");
FileReader fr = new FileReader(file);
24.3.1.3.2FileReader(Nombre de archivo de cadena)
/* 格式:
	public FileReader(File file) 
	作用:使用文件名称创建流对象*/
FileReader fr = new FileReader("b.txt");

24.3.1.4 Métodos de miembros comunes

  • readMétodo, puede leer datos un carácter a la vez, promoverlos al tipo int, leer hasta el final del archivo y regresar-1
  • read(char[] cbuf), cada vez que se lee la longitud de b en la matriz, se devuelve el número de caracteres válidos leídos. Cuando se llega al final de la lectura, se devuelve el número de caracteres.-1
24.3.1.4.1leer()
/* 格式:
	FileReader对象.read()
	作用:每次可以读取一个字符的数据*/
int b = fr.read())

ilustrar:

Cada vez que se lee un carácter, se promoverá automáticamente al tipo int, por lo que es necesario realizar una conversión para obtener los datos.

24.3.1.4.2leer(char[] cbuf)
/* 格式:
	FileReader对象.(char[] cbuf)
	作用:每次读取b的长度个字符到数组中*/

char[] cbuf = new char[2];
// 循环读取
int  len = fr.read(cbuf)

ilustrar:

Se combinan los tres pasos de lectura de datos, decodificación y conversión forzada, y los caracteres después de la conversión forzada se colocan en la matriz.

24.3.1.4.4cerrar()
/* 格式:
	FileReader对象.close()
   作用:释放资源 */
fis.close();

ilustrar:

Liberar ocupación de recursos

24.3.1.5 Lectura de bucle

Bucle: lectura de un solo carácter

// 使用文件名称创建流对象
FileReader fr = new FileReader("read.txt");
// 定义变量,保存数据
int b ;
// 循环读取
while ((b = fr.read())!=-1) {
    
    
    System.out.println((char)b); //黑马程序员
}
// 关闭资源
fr.close();

Bucle: lectura de matriz de caracteres

// 使用文件名称创建流对象
FileReader fr = new FileReader("read.txt");
// 定义变量,保存有效字符个数
int len;
// 定义字符数组,作为装字符数据的容器
char[] cbuf = new char[2];
// 循环读取
while ((len = fr.read(cbuf))!=-1) {
    
    
    System.out.println(new String(cbuf));
}
// 关闭资源
fr.close();

24.3.1.6 Principio

El principio subyacente del flujo de entrada de caracteres

imagen-20230427103636695

ilustrar:

imagen-20230427103809065

imagen-20230427104056436

ilustrar:

Cuando se ejecuta el código, la depuración del punto de interrupción se puede

Ejemplo

 FileReader fr = new FileReader("myio\\b.txt");
        fr.read();//会把文件中的数据放到缓冲区当中

        //清空文件
        FileWriter fw = new FileWriter("myio\\b.txt");

        //请问,如果我再次使用fr进行读取
        //会读取到数据吗?

        //会把缓冲区中的数据全部读取完毕

        //正确答案:
        //但是只能读取缓冲区中的数据,文件中剩余的数据无法再次读取
        int ch;
        while((ch = fr.read()) != -1){
    
    
            System.out.println((char)ch);
        }


        fw.close();
        fr.close();

24.3.2 Flujo de salida-FileWriter

24.3.2.1 Descripción general

La clase abstractajava.io.Writer es la superclase que representa todas las clases utilizadas para escribir secuencias de caracteres, escribiendo información de caracteres especificada en el destino. Define los métodos funcionales básicos comunes de los flujos de salida de bytes.

24.3.2.2 Casos de uso básicos

//1.创建对象并关联本地文件
FileWriter fw = new FileWriter("myio\\a.txt",true);
//2.写出数据 write()
fw.write(25105);
//3.释放资源
fw.close();

24.3.2.3 Método de construcción

imagen-20230427100417262

24.3.2.3.1FileWriter(Archivo de archivo)
/* 格式:
	public FileWriter(File file)
	作用:使用File对象创建流对象*/
File file = new File("a.txt");
FileWriter fw = new FileWriter(file);

detalle:

  • Si el archivo no existe, se creará un archivo nuevo, pero la ruta principal debe existir.
  • Si el archivo ya existe, se borrará. Si no desea borrarlo, puede activar el interruptor de continuación.
24.3.2.3.2FileWriter(Nombre de ruta de cadena)
/* 格式:
	public FileWriter(File file)
	作用:使用文件名称创建流对象*/

 FileWriter fw = new FileWriter("b.txt");

detalle:

Lo mismo que arriba

24.3.2.4 Métodos de miembros comunes

imagen-20230427100521001

imagen-20230427105116231

24.3.2.3.3escribir(int/cadena c)
/* 格式:
	FileWriter对象.write(int/string c)
	作用:写出一个字符*/
fw.write(97);
fw.write('C');

Aviso:

  • No se llama al método de cierre, los datos solo se guardan en el búfer y no se escriben en el archivo.
  • Si el parámetro del método de escritura es un número entero, pero lo que realmente se escribe en el archivo local es el carácter correspondiente al número entero en el conjunto de caracteres
24.3.2.3.4escribir(char[] cbuf)
/* 格式:
	FileWriter对象.write(char[] cbuf)
	作用:写出一个字符数组*/
char[] chars = "黑马程序员".toCharArray();
fw.write(chars); // 黑马程序员
24.3.2.3.5escribir(char[] cbuf, int off, int len)
/* 格式:
	FileWriter对象.write(char[] cbuf, int off, int len)
	作用:写出字符数组的一部分*/
char[] chars = "黑马程序员".toCharArray();
fw.write(b,2,2); // 程序
24.3.2.3.6descarga()
/* 格式:
	FileWriter对象.flush()
	作用:将缓冲区中的数据,刷新到本地文件中*/
public class FWWrite {
    
    
    public static void main(String[] args) throws IOException {
    
    
        // 使用文件名称创建流对象
        FileWriter fw = new FileWriter("fw.txt");
        // 写出数据,通过flush
        fw.write('刷'); // 写出第1个字符
        fw.flush();
        fw.write('新'); // 继续写出第2个字符,写出成功
        fw.flush();
      
      	// 写出数据,通过close
        fw.write('关'); // 写出第1个字符
        fw.close();
        fw.write('闭'); // 继续写出第2个字符,【报错】java.io.IOException: Stream closed
        fw.close();
    }
}

Aviso:

Incluso si el método de descarga escribe los datos, se debe llamar al método de cierre al final de la operación para liberar recursos del sistema.

24.3.2.3.7cerrar()
/* 格式:
	FileWriter对象.close()
   作用:释放资源 */
fis.close();

ilustrar:

Liberar ocupación de recursos

24.3.2.5 Continuación y nueva línea

public class FWWrite {
    
    
    public static void main(String[] args) throws IOException {
    
    
        // 使用文件名称创建流对象,可以续写数据
        FileWriter fw = new FileWriter("fw.txt"true);     
      	// 写出字符串
        fw.write("黑马");
      	// 写出换行
      	fw.write("\r\n");
      	// 写出字符串
  		fw.write("程序员");
      	// 关闭资源
        fw.close();
    }
}
输出结果:
黑马
程序员

ilustrar:

Escribir manualmente saltos de línea en el programa

24.3.2.6 Principio

El principio del flujo de salida del flujo básico de caracteres.

imagen-20230427105006872

ilustrar:

  • Al escribir datos, Java primero los escribirá en el búfer de memoria.
  • Cuando la longitud del búfer alcance los 8192 bytes, se escribirá automáticamente en el archivo.
  • Cuando se cierra la secuencia IO, el contenido del área de caché también se escribirá automáticamente en el archivo.

Juego de caracteres 24,4

Resumen de notas:

  1. Definición: método para asignar caracteres en un juego de caracteres a uno o más números.
  2. Razones de los caracteres confusos: leer datos , no leer los datos completos y el método del conjunto de caracteres al decodificar y codificar no es uniforme.
  3. Codificación y decodificación en Java:
    • La codificación GBK utiliza dos bytes para almacenar un carácter chino.
    • La codificación UTF-8 utiliza tres bytes para almacenar un carácter chino.

24.4.1 Definición

El juego de caracteres (juego de caracteres) es un método para asignar caracteres en un juego de caracteres a uno o más números.

imagen-20230427093521471

imagen-20230427093511799

24.4.2 Causas de códigos confusos

imagen-20230427092438753

imagen-20230427092605878

imagen-20230427092531144

24.4.3 Codificación y decodificación en Java

imagen-20230427093209309

Ejemplo:

//1.编码
String str = "ai你哟";
byte[] bytes1 = str.getBytes();
System.out.println(Arrays.toString(bytes1));

byte[] bytes2 = str.getBytes("GBK");
System.out.println(Arrays.toString(bytes2));


//2.解码
String str2 = new String(bytes1);
System.out.println(str2);

String str3 = new String(bytes1,"GBK");
System.out.println(str3);

ilustrar:

  • La codificación GBK utiliza dos bytes para almacenar un carácter chino.
  • La codificación UTF-8 utiliza tres bytes para almacenar un carácter chino.

24.4 Flujos almacenados en búfer

Resumen de notas:

  1. Descripción general: el flujo de búfer, también llamado flujo de alta eficiencia , es una mejora de los cuatro FileXxx flujos básicos , que empaqueta flujos básicos en flujos avanzados y mejora el rendimiento de lectura/escritura de datos.

  2. Flujo de búfer de bytes:

    • Flujo de entrada BufferedInputStream :

      // 1.创建流对象
      BufferedInputStream bis = new BufferedInputStream(new FileInputStream("jdk9.exe"));
      // 2.读取数据
      int b = bis.read();
      // 3.关闭资源
      bis.close();
      
    • Flujo de salida BufferedOutputStream

      // 1.创建流对象
      BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.exe"));
      // 2.写出数据
      int len;
      byte[] bytes = new byte[8*1024];
      bos.write(bytes, 0 , len);
      // 3.关闭资源
      bis.close();
      
  3. flujo de buffer de caracteres

    • Flujo de entrada BufferedReader

      // 1.创建流对象
      BufferedReader br = new BufferedReader(new FileReader("in.txt"));
      // 2.读取数据
      String line = bis.readLine();
      // 3.关闭资源
      br.close();
      
    • Flujo de salida BufferedWriter

      // 1.创建流对象
      BufferedWriter bw = new BufferedWriter(new FileWriter("out.txt"));
      // 2.写出数据
      bw.write("黑马");
      // 3.写出换行
      bw.newLine();
      // 4.关闭资源
      bw.close();
      
  4. El principio subyacente: para aumentar la eficiencia del búfer, se abre un área en la memoria y se denomina búfer . La función del búfer reduce la lectura y escritura frecuentes en la memoria y el disco duro , mejorando así la eficiencia de lectura y escritura del área del disco duro.

    imagen-20230812104312395

24.4.1 Descripción general

24.4.1.1 Definición

​ Los flujos almacenados en búfer, también llamados flujos eficientes, son mejoras de los cuatro FileXxxflujos básicos. Envuelven los flujos básicos en flujos avanzados para mejorar el rendimiento de la lectura/escritura de datos.

Clasificados según tipo de datos:

  • Flujo almacenado en bytes : BufferedInputStream,BufferedOutputStream
  • Flujo de búfer de caracteres : BufferedReader,BufferedWriter

24.4.4.2 Arquitectura

imagen-20230427112305233

24.4.2 Flujo almacenado en búfer de bytes

24.4.2.1 Flujo de entrada-BufferedInputStream

24.4.2.1.1 Descripción general

BufferedInputStreamEs una clase de flujo de entrada proporcionada por la biblioteca Java I / O. Utiliza un búfer interno para mejorar la eficiencia de la lectura de archivos.

24.4.2.1.2 Casos de uso básicos
// 1.创建流对象
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("jdk9.exe"));
// 2.读取数据
int b = bis.read();
// 3.关闭资源
bis.close();
24.4.2.1.3 Método de construcción
  • public BufferedInputStream(InputStream in): crea un nuevo flujo de entrada almacenado en búfer.
/* 格式:
	public BufferedInputStream(InputStream in)
    作用:创建字节缓冲输入流*/
// 创建字节缓冲输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bis.txt"));

ilustrar:

imagen-20230427114025839

  • Al utilizar este constructor, Java creará una nueva matriz interna con una longitud de 8192 bytes.
24.4.2.1.4 Métodos de miembros comunes

Consulte el flujo de entrada del flujo elemental de bytes.

24.4.2.2 Flujo de salida: BufferedOutputStream

24.4.2.2.1 Descripción general
24.4.2.2.2 Casos de uso básicos
// 1.创建流对象
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.exe"));
// 2.写出数据
int len;
byte[] bytes = new byte[8*1024];
bos.write(bytes, 0 , len);
// 3.关闭资源
bis.close();
24.4.2.2.3Método de construcción
/* 格式:
	public BufferedOutputStream(OutputStream os)
    作用:创建字节缓冲输出流对象*/
 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myio\\a.txt"));

ilustrar:

imagen-20230427114223961

  • Al utilizar este constructor, Java creará una nueva matriz interna con una longitud de 8192 bytes.
24.4.2.2.4 Métodos de miembros comunes

Consulte el flujo de salida del flujo elemental de bytes.

24.4.2.3 Caso – Copia de archivo

// 方式一:
//1.创建缓冲流的对象
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("myio\\a.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myio\\a.txt"));
//2.循环读取并写到目的地
int b;
while ((b = bis.read()) != -1) {
    
    
    bos.write(b);
}
//3.释放资源
bos.close();
bis.close();

// -----------------------

// 方式二:
//1.创建缓冲流的对象
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("myio\\a.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myio\\copy2.txt"));
//2.拷贝(一次读写多个字节)
byte[] bytes = new byte[1024];
int len;
while((len = bis.read(bytes)) != -1){
    
    
    bos.write(bytes,0,len);
}
//3.释放资源
bos.close();
bis.close();

consejos:

Cuando se utiliza una secuencia almacenada en búfer para crear un objeto, solo es necesario liberar los recursos del objeto de secuencia almacenado en búfer, y no es necesario liberar los recursos de los objetos de secuencia de entrada y salida del archivo. Porque Java cerrará automáticamente la operación en la parte inferior.

imagen-20230427114552934

24.4.4.4 Principio

Principio de alta eficiencia del flujo de búfer de bytes

imagen-20230427134512840

ilustrar:

Para aumentar la eficiencia del búfer, se abre un área en la memoria y se denomina búfer. La función del búfer reduce la lectura y escritura frecuentes de la memoria y el disco duro, mejorando así la eficiencia de lectura y escritura del área del disco duro.

imagen-20230427134445862

ilustrar:

Al leer y escribir datos definiendo una matriz, en realidad acelera la lectura y escritura frecuente de datos en la memoria, mejorando así la eficiencia de lectura y escritura del área de memoria.

24.4.3 Flujos de caracteres almacenados en búfer

24.4.3.1 Flujo de entrada-BufferedReader

24.4.3.1.1 Descripción general

EsBufferedReader un flujo de entrada de búfer de caracteres en Java, que puede proporcionar un método para leer una o más líneas de datos de texto a la vez y puede garantizar la lectura secuencial del flujo de entrada.

24.4.3.1.2 Casos de uso básicos
// 1.创建流对象
BufferedReader br = new BufferedReader(new FileReader("in.txt"));
// 2.读取数据
String line = bis.readLine();
// 3.关闭资源
br.close();
24.4.3.1.3 Método de construcción
/* 格式:
	public BufferedReader(Reader in) 
	作用:创建字符缓冲输入流对象*/
// 示例
BufferedReader br = new BufferedReader(new FileReader("br.txt"));
24.4.3.1.4 Métodos de miembros comunes
  • public String readLine(): Leer una línea de texto.
  • Para conocer otros métodos comunes, consulte Flujo de entrada básico de caracteres.
24.4.3.1.4.1leerLínea()
/* 格式:
	BufferedReader对象.readLine()
	作用:每次可以读取一个字符的数据*/
 String line = br.readLine()

24.4.3.2 Flujo de salida-BufferedWriter

24.4.3.2.1 Descripción general

EsBufferedWriter un flujo de salida de caracteres en Java IO. Se utiliza para escribir datos de texto en el flujo de salida de caracteres. Puede proporcionar un mecanismo de almacenamiento en búfer para mejorar la eficiencia de la escritura.

24.4.3.2.2 Casos de uso básicos
// 1.创建流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("out.txt"));
// 2.写出数据
bw.write("黑马");
// 3.写出换行
bw.newLine();
// 4.关闭资源
bw.close();
24.4.3.2.3Método de construcción
/* 格式:
	public BufferedReader(Reader in) 
	作用:创建字符缓冲输出流对象*/
BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"))
24.4.3.2.4 Métodos de miembros comunes
  • public void newLine(): Escriba un separador de línea, el símbolo está definido por la propiedad del sistema.
  • Para conocer otros métodos comunes, consulte Flujo de salida básico de caracteres.
/* 格式:
	BufferedWriter对象.newLine()
	作用:换行*/
bw.newLine();

24.4.3.3 Métodos de miembros

ilustrar:

El método de salida único juzgará qué carácter de nueva línea usar según el sistema operativo actual.

24.4.4.4 Principio

El principio básico de las secuencias almacenadas en búfer es que al crear un objeto de secuencia, se creará una matriz de búfer incorporada de tamaño predeterminado (longitud 8192). A través de la lectura y escritura del búfer, se puede reducir la cantidad de E/S del sistema, mejorando así la eficiencia. de lectura y escritura.

​ Consulte la sección anterior字节缓冲流的原理

24.5 Flujo de conversión

Resumen de notas:

  1. Descripción general: lea bytes y decodifíquelos en caracteres utilizando el conjunto de caracteres especificado . También se puede lograr la conversión de codificación del juego de caracteres cuando se lee
  2. Corriente de entradaInputStreamReader _
  3. Flujo de salidaSalidaStreamWriter _

24.5.1 Descripción general

24.5.1.1 Definición

El flujo de conversión java.io.InputStreamReaderes una subclase de Reader y un puente entre el flujo de bytes y el flujo de caracteres. Lee bytes y los decodifica en caracteres utilizando el conjunto de caracteres especificado. Su juego de caracteres se puede especificar por nombre o puede aceptar el juego de caracteres predeterminado de la plataforma.

imagen-20230427210449500

24.5.1.1 Arquitectura

imagen-20230427210243751

24.5.2 Flujo de entrada-InputStreamReader

24.5.2.1 Método de construcción

  • InputStreamReader(InputStream in): crea una secuencia de caracteres utilizando el juego de caracteres predeterminado.
  • InputStreamReader(InputStream in, String charsetName): crea una secuencia de caracteres del conjunto de caracteres especificado.

Ejemplo:

InputStreamReader isr = new InputStreamReader(new FileInputStream("in.txt"));
InputStreamReader isr2 = new InputStreamReader(new FileInputStream("in.txt") , "GBK");

24.5.2.2 Métodos de miembros comunes

  • Para conocer métodos comunes, consulte Flujo de entrada básico de caracteres.

Ejemplo:

public class ReaderDemo2 {
    
    
    public static void main(String[] args) throws IOException {
    
    
      	// 定义文件路径,文件为gbk编码
        String FileName = "E:\\file_gbk.txt";
      	// 创建流对象,默认UTF8编码
        InputStreamReader isr = new InputStreamReader(new FileInputStream(FileName));
      	// 创建流对象,指定GBK编码
        InputStreamReader isr2 = new InputStreamReader(new FileInputStream(FileName) , "GBK");
		// 定义变量,保存字符
        int read;
      	// 使用默认编码字符流读取,乱码
        while ((read = isr.read()) != -1) {
    
    
            System.out.print((char)read); // ��Һ�
        }
        isr.close();
      
      	// 使用指定编码字符流读取,正常解析
        while ((read = isr2.read()) != -1) {
    
    
            System.out.print((char)read);// 大家好
        }
        isr2.close();
    }
}

ilustrar:

El código anterior se reemplaza por el flujo de entrada básico de caracteres en JDK11

FileReader fr = new FileReader("myio\\gbkfile.txt", Charset.forName("GBK"));
//2.读取数据
int ch;
while ((ch = fr.read()) != -1){
    
    
    System.out.print((char)ch);
}
//3.释放资源
fr.close();

24.5.3 Flujo de salida-OutputStreamWriter

24.5.3.1 Método de construcción

  • OutputStreamWriter(OutputStream in): crea una secuencia de caracteres utilizando el juego de caracteres predeterminado.
  • OutputStreamWriter(OutputStream in, String charsetName): crea una secuencia de caracteres del conjunto de caracteres especificado.

Ejemplo:

OutputStreamWriter isr = new OutputStreamWriter(new FileOutputStream("out.txt"));
OutputStreamWriter isr2 = new OutputStreamWriter(new FileOutputStream("out.txt") , "GBK");

24.5.3.2 Métodos de miembros comunes

  • Para conocer métodos comunes, consulte Flujo de salida básico de caracteres.

Ejemplo:

public class OutputDemo {
    
    
    public static void main(String[] args) throws IOException {
    
    
      	// 定义文件路径
        String FileName = "E:\\out.txt";
      	// 创建流对象,默认UTF8编码
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(FileName));
        // 写出数据
      	osw.write("你好"); // 保存为6个字节
        osw.close();
      	
		// 定义文件路径
		String FileName2 = "E:\\out2.txt";
     	// 创建流对象,指定GBK编码
        OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream(FileName2),"GBK");
        // 写出数据
      	osw2.write("你好");// 保存为4个字节
        osw2.close();
    }
}

ilustrar:

El código anterior se reemplaza por el flujo de salida básico de caracteres en JDK11.

FileWriter fw = new FileWriter("myio\\c.txt", Charset.forName("GBK"));
fw.write("你好你好");
fw.close();

24.5.4 Conversión de codificación de caso-archivo

//1.JDK11以前的方案
/* InputStreamReader isr = new InputStreamReader(new FileInputStream("myio\\b.txt"),"GBK");
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myio\\d.txt"),"UTF-8");

        int b;
        while((b = isr.read()) != -1){
            osw.write(b);
        }

        osw.close();
        isr.close();*/

//2.替代方案
FileReader fr = new FileReader("myio\\b.txt", Charset.forName("GBK"));
FileWriter fw = new FileWriter("myio\\e.txt",Charset.forName("UTF-8"));
int b;
while ((b = fr.read()) != -1){
    
    
    fw.write(b);
}
fw.close();
fr.close();

24.6 Serialización de flujos

Resumen de notas:

  1. 对象的数据Descripción general: un objeto se puede representar mediante una secuencia de bytes, que contiene información como esta 对象的类型y . Guarda persistentemente información sobre un objeto.对象中存储的属性
  2. Flujo de serialización ObjectOutputStream : escribe el tipo de datos original de los objetos Java en archivos para lograr un almacenamiento persistente de objetos.
  3. Deserializar la secuencia ObjectInputStream : restaura datos sin procesar previamente serializados usando ObjectOutputStream en objetos.

24.6.1 Descripción general

24.6.1.1 Definición

Java proporciona un mecanismo para la serialización de objetos . Un objeto se puede representar mediante una secuencia de bytes que contiene 对象的数据, 对象的类型y 对象中存储的属性otra información. Una vez escrita la secuencia de bytes en el archivo, equivale a conservar la información de un objeto en el archivo .

24.6.1.1 Arquitectura

imagen-20230427214856115

24.6.2 Flujo de serialización-ObjectOutputStream

24.6.2.1 Descripción general

Clasejava.io.ObjectOutputStream , escribe el tipo de datos original de los objetos Java en archivos para lograr un almacenamiento persistente de los objetos.

24.6.2.2 Métodos de construcción

  • public ObjectOutputStream(OutputStream out) : Cree un ObjectOutputStream especificando el OutputStream

ObjectOutputStream(OutputStream fuera)

/* 格式:
	public ObjectOutputStream(OutputStream out)
    作用:创建序列化流*/
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("employee.txt"));

Aviso:

  • Esta clase debe implementar java.io.Serializable la interfaz, Serializableque es una interfaz de marcador. Las clases que no implementan esta interfaz no serializarán ni deserializarán ningún estado y arrojarán NotSerializableException.

  • Todas las propiedades de esta clase deben ser serializables. Si hay un atributo que no necesita ser serializable, el atributo debe marcarse como transitorio y modificarse mediante la transientpalabra clave.

  • Ejemplo:

    public class Employee implements java.io.Serializable {
           
           
        public String name;
        public String address;
        public transient int age; // transient瞬态修饰成员,不会被序列化
        public void addressCheck() {
           
           
          	System.out.println("Address  check : " + name + " -- " + address);
        }
    }
    

24.6.2.3 Métodos de miembros

  • public final void writeObject (Object obj): Escribe el objeto especificado.
/* 格式:
	ObjectOutputStream对象.writeObject(Object obj)
    作用:将指定的对象写出*/
out.writeObject(e);

24.6.3 Flujo de deserialización-ObjectInputStream

24.6.2.1 Descripción general

ObjectInputStreamDeserialice la secuencia, restaurando los datos sin procesar previamente serializados usando un ObjectOutputStream en un objeto.

24.6.3.2 Método de construcción

  • public ObjectInputStream(InputStream in) : cree un ObjectInputStream especificando el InputStream.

ObjectOutputStream(OutputStream fuera)

/* 格式:
	public ObjectInputStream(InputStream in) 
    作用:创建反序列化流*/
ObjectInputStream in = new ObjectInputStream(new FileInputStream("employee.txt"));

Aviso:

  1. Para que la JVM deserialice un objeto, debe ser una clase que pueda encontrar el archivo de clase. Si no se puede encontrar el archivo de clase para la clase, ClassNotFoundExceptionse lanza una excepción.
  2. Cuando la JVM deserializa el objeto, se puede encontrar el archivo de clase, pero si el archivo de clase se modifica después de serializar el objeto, la operación de deserialización también fallará y se generará una InvalidClassExceptionexcepción. El motivo de esta excepción es el siguiente:
    • El número de versión de serie de la clase no coincide con el número de versión del descriptor de clase leído en la secuencia
    • Esta clase contiene un tipo de datos desconocido.
    • Esta clase no tiene un constructor sin parámetros accesible.

Ejemplo:

Al crear una clase, agregue el número de versión.

public class Employee implements java.io.Serializable {
     
     
     // 加入序列版本号
     private static final long serialVersionUID = 1L;
     public String name;
     public String address;
     // 添加新的属性 ,重新编译, 可以反序列化,该属性赋为默认值.
     public int eid; 

     public void addressCheck() {
     
     
         System.out.println("Address  check : " + name + " -- " + address);
     }
}

24.6.3.2 Métodos de miembros

  • public final Object readObject (): Leer un objeto.

leerObjeto()

/* 格式:
	ObjectInputStream对象.readObject ()
    作用:读取一个对象*/
e = (Employee) in.readObject();

24.6.4 Caso: serialización y deserialización de múltiples archivos

Ejemplo:

Student s1 = new Student("zhangsan",23,"南京");
Student s2 = new Student("lisi",24,"重庆");
Student s3 = new Student("wangwu",25,"北京");

ArrayList<Student> list = new ArrayList<>();

list.add(s1);
list.add(s2);
list.add(s3);

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myio\\a.txt"));
oos.writeObject(list);

oos.close();
//1.创建反序列化流的对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myio\\a.txt"));

//2.读取数据
ArrayList<Student> list = (ArrayList<Student>) ois.readObject();

for (Student student : list) {
    
    
    System.out.println(student);
}

//3.释放资源
ois.close();

24.7 Flujo de impresión

Resumen de notas:

  1. Descripción general: java.io.PrintStreamclase, esta clase puede imprimir cómodamente valores de varios tipos de datos y es un método de salida conveniente.
  2. Flujo de impresión de caracteres PrintWriter : necesita enviar datos de texto a archivos y otros lugares, y necesita una codificación de caracteres más rica y manejo de excepciones
  3. Flujo de impresión de bytes PrintStream : simplemente necesita enviar datos de texto a la consola o al archivo

24.7.1 Descripción general

24.7.1.1 Definición

Por lo general, imprimimos en la consola llamando a printmétodos y printlnmétodos. Estos dos métodos provienen de java.io.PrintStreamclases. Esta clase puede imprimir convenientemente valores de varios tipos de datos, lo cual es un método de salida conveniente.

Aviso:

​ Flujo de impresión, solo se puede leer, no escribir

24.7.1.2 Arquitectura

imagen-20230428101730628

24.7.2 Flujo de impresión de caracteres PrintWriter

24.7.2.1 Descripción general

24.7.2.2 Método de construcción

imagen-20230428093515791

Aviso:

Hay un búfer en la parte inferior del flujo de caracteres. Si desea actualizar automáticamente, debe habilitarlo.

/* 格式:
	public PrintWriter(OutpusStream out, boolean autoFlush);
    作用:创建打印流*/
PrintStream ps = new PrintStream(new FileOutputStream("myio\\a.txt"), true);

24.7.2.3 Métodos de miembros

imagen-20230428093552198

/* 格式:
	PrintWriter对象.println(xxx b )
    作用:将指定的对象写出*/
 ps.println(97);

24.7.3 Flujo de impresión de bytes PrintStream

24.7.3.1 Descripción general

24.7.3.2 Método de construcción

imagen-20230428092434871

Aviso:

No hay ningún búfer en la parte inferior del flujo de bytes y no importa si la actualización automática está activada o no.

/* 格式:
	public PrintStream(OutpusStream out, boolean autoFlush, String encoding);
    作用:创建打印流*/
PrintStream ps = new PrintStream(new FileOutputStream("myio\\a.txt"), true, Charset.forName("UTF-8"));

24.7.3.3 Métodos de miembros

imagen-20230428092734270

imprimir ()

/* 格式:
	PrintStream对象.println(xxx b )
    作用:将指定的对象写出*/
 ps.println(97);//写出 + 自动刷新 + 自动换行

detalle:

  • Aquí, salida tal como está en el archivo.

    imagen-20230428093326196

24.7.4 Caso: Cambio del flujo de impresión

public class PrintDemo {
    
    
    public static void main(String[] args) throws IOException {
    
    
		// 调用系统的打印流,控制台直接输出97
        System.out.println(97);
      
		// 创建打印流,指定文件的名称
        PrintStream ps = new PrintStream("ps.txt");
      	
      	// 设置系统的打印流流向,输出到ps.txt
        System.setOut(ps);
      	// 调用系统的打印流,ps.txt中输出97
        System.out.println(97);
    }
}

ilustrar:

El método System.out.println() que utilizamos habitualmente es el método de programación en cadena de flujos de impresión avanzados.

24.8 Comprimir y descomprimir flujos (comprensión)

Resumen de notas:

​ Descripción general: archivos o carpetas comprimidos

24.8.1 Descripción general

24.8.1.1 Significado

Responsable de comprimir archivos o carpetas.

24.8.1.2 Arquitectura

imagen-20230428101544436

24.8.2 Descomprimir flujos

/*
*   解压缩流
*
* */
public class ZipStreamDemo1 {
    
    
    public static void main(String[] args) throws IOException {
    
    

        //1.创建一个File表示要解压的压缩包
        File src = new File("D:\\aaa.zip");
        //2.创建一个File表示解压的目的地
        File dest = new File("D:\\");

        //调用方法
        unzip(src,dest);

    }

    //定义一个方法用来解压
    public static void unzip(File src,File dest) throws IOException {
    
    
        //解压的本质:把压缩包里面的每一个文件或者文件夹读取出来,按照层级拷贝到目的地当中
        //创建一个解压缩流用来读取压缩包中的数据
        ZipInputStream zip = new ZipInputStream(new FileInputStream(src));
        //要先获取到压缩包里面的每一个zipentry对象
        //表示当前在压缩包中获取到的文件或者文件夹
        ZipEntry entry;
        while((entry = zip.getNextEntry()) != null){
    
    
            System.out.println(entry);
            if(entry.isDirectory()){
    
    
                //文件夹:需要在目的地dest处创建一个同样的文件夹
                File file = new File(dest,entry.toString());
                file.mkdirs();
            }else{
    
    
                //文件:需要读取到压缩包中的文件,并把他存放到目的地dest文件夹中(按照层级目录进行存放)
                FileOutputStream fos = new FileOutputStream(new File(dest,entry.toString()));
                int b;
                while((b = zip.read()) != -1){
    
    
                    //写到目的地
                    fos.write(b);
                }
                fos.close();
                //表示在压缩包中的一个文件处理完毕了。
                zip.closeEntry();
            }
        }
        zip.close();
    }
}

24.8.3 Flujos comprimidos

public class ZipStreamDemo2 {
    
    
    public static void main(String[] args) throws IOException {
    
    
        /*
         *   压缩流
         *      需求:
         *          把D:\\a.txt打包成一个压缩包
         * */
        //1.创建File对象表示要压缩的文件
        File src = new File("D:\\a.txt");
        //2.创建File对象表示压缩包的位置
        File dest = new File("D:\\");
        //3.调用方法用来压缩
        toZip(src,dest);
    }

    /*
    *   作用:压缩
    *   参数一:表示要压缩的文件
    *   参数二:表示压缩包的位置
    * */
    public static void toZip(File src,File dest) throws IOException {
    
    
        //1.创建压缩流关联压缩包
        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(new File(dest,"a.zip")));
        //2.创建ZipEntry对象,表示压缩包里面的每一个文件和文件夹
        //参数:压缩包里面的路径
        ZipEntry entry = new ZipEntry("aaa\\bbb\\a.txt");
        //3.把ZipEntry对象放到压缩包当中
        zos.putNextEntry(entry);
        //4.把src文件中的数据写到压缩包当中
        FileInputStream fis = new FileInputStream(src);
        int b;
        while((b = fis.read()) != -1){
    
    
            zos.write(b);
        }
        zos.closeEntry();
        zos.close();
    }
}
public class ZipStreamDemo3 {
    
    
    public static void main(String[] args) throws IOException {
    
    
        /*
         *   压缩流
         *      需求:
         *          把D:\\aaa文件夹压缩成一个压缩包
         * */
        //1.创建File对象表示要压缩的文件夹
        File src = new File("D:\\aaa");
        //2.创建File对象表示压缩包放在哪里(压缩包的父级路径)
        File destParent = src.getParentFile();//D:\\
        //3.创建File对象表示压缩包的路径
        File dest = new File(destParent,src.getName() + ".zip");
        //4.创建压缩流关联压缩包
        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(dest));
        //5.获取src里面的每一个文件,变成ZipEntry对象,放入到压缩包当中
        toZip(src,zos,src.getName());//aaa
        //6.释放资源
        zos.close();
    }

    /*
    *   作用:获取src里面的每一个文件,变成ZipEntry对象,放入到压缩包当中
    *   参数一:数据源
    *   参数二:压缩流
    *   参数三:压缩包内部的路径
    * */
    public static void toZip(File src,ZipOutputStream zos,String name) throws IOException {
    
    
        //1.进入src文件夹
        File[] files = src.listFiles();
        //2.遍历数组
        for (File file : files) {
    
    
            if(file.isFile()){
    
    
                //3.判断-文件,变成ZipEntry对象,放入到压缩包当中
                ZipEntry entry = new ZipEntry(name + "\\" + file.getName());//aaa\\no1\\a.txt
                zos.putNextEntry(entry);
                //读取文件中的数据,写到压缩包
                FileInputStream fis = new FileInputStream(file);
                int b;
                while((b = fis.read()) != -1){
    
    
                    zos.write(b);
                }
                fis.close();
                zos.closeEntry();
            }else{
    
    
                //4.判断-文件夹,递归
                toZip(file,zos,name + "\\" + file.getName());
                //     no1            aaa   \\   no1
            }
        }
    }
}

24.9 Herramientas

Resumen de notas:

  • La clase de herramienta Commons-io es un conjunto de kits de herramientas de código abierto relacionados con operaciones de IO proporcionados por Apache Open Source Foundation (comprender)
  • Clase de herramienta Hutool (puntos clave):
    • HutoolEs una biblioteca de herramientas Java fácil de usar y rica en funciones . Mediante el uso de muchas clases de herramientas prácticas, está diseñada para ayudar a los desarrolladores a completar diversas tareas de desarrollo de manera rápida y conveniente. Estas herramientas encapsuladas cubren una serie de operaciones como cadenas, números, colecciones, codificaciones, fechas, archivos, IO, cifrado, bases de datos JDBC, JSON, clientes HTTP, etc., y pueden satisfacer diversas necesidades de desarrollo.
    • Sitio web oficial: Introducción e instalación (oschina.io)

imagen-20230812115134019

24.9.1 Commos-io

24.9.1.1 Descripción general

Commons-io es un conjunto de herramientas de código abierto relacionadas con operaciones de IO proporcionadas por Apache Open Source Foundation.

Función: Mejorar la eficiencia de desarrollo del flujo I0.

imagen-20230428102331425

24.9.1.2 Métodos comunes de la clase FileUtils

imagen-20230428102427925

24.9.1.3 Métodos comunes de la clase IOUtils

imagen-20230428102454674

24.9.1.4 Uso básico de casos

public class CommonsIODemo1 {
    
    
    public static void main(String[] args) throws IOException {
    
    
        /*
          FileUtils类
                static void copyFile(File srcFile, File destFile)                   复制文件
                static void copyDirectory(File srcDir, File destDir)                复制文件夹
                static void copyDirectoryToDirectory(File srcDir, File destDir)     复制文件夹
                static void deleteDirectory(File directory)                         删除文件夹
                static void cleanDirectory(File directory)                          清空文件夹
                static String readFileToString(File file, Charset encoding)         读取文件中的数据变成成字符串
                static void write(File file, CharSequence data, String encoding)    写出数据

            IOUtils类
                public static int copy(InputStream input, OutputStream output)      复制文件
                public static int copyLarge(Reader input, Writer output)            复制大文件
                public static String readLines(Reader input)                        读取数据
                public static void write(String data, OutputStream output)          写出数据
         */


        /* File src = new File("myio\\a.txt");
        File dest = new File("myio\\copy.txt");
        FileUtils.copyFile(src,dest);*/


        /*File src = new File("D:\\aaa");
        File dest = new File("D:\\bbb");
        FileUtils.copyDirectoryToDirectory(src,dest);*/

        /*File src = new File("D:\\bbb");
        FileUtils.cleanDirectory(src);*/
    }
}

24.9.2Hutool (énfasis)

imagen-20230428103211173

24.9.2.1 Descripción general

​ Commons es un conjunto de herramientas de código abierto desarrollado por chinos, que contiene muchas API que nos ayudan a mejorar la eficiencia del desarrollo.

14.9.2.2 Clase de herramienta

imagen-20230428103826401

14.9.2.3 Uso básico de casos

public class Test1 {
    
    
    public static void main(String[] args) {
    
    
    /*
        FileUtil类:
                file:根据参数创建一个file对象
                touch:根据参数创建文件

                writeLines:把集合中的数据写出到文件中,覆盖模式。
                appendLines:把集合中的数据写出到文件中,续写模式。
                readLines:指定字符编码,把文件中的数据,读到集合中。
                readUtf8Lines:按照UTF-8的形式,把文件中的数据,读到集合中

                copy:拷贝文件或者文件夹
    */


       /* File file1 = FileUtil.file("D:\\", "aaa", "bbb", "a.txt");
        System.out.println(file1);//D:\aaa\bbb\a.txt

        File touch = FileUtil.touch(file1);
        System.out.println(touch);


        ArrayList<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("aaa");
        list.add("aaa");

        File file2 = FileUtil.writeLines(list, "D:\\a.txt", "UTF-8");
        System.out.println(file2);*/

      /*  ArrayList<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("aaa");
        list.add("aaa");
        File file3 = FileUtil.appendLines(list, "D:\\a.txt", "UTF-8");
        System.out.println(file3);*/
        List<String> list = FileUtil.readLines("D:\\a.txt", "UTF-8");
        System.out.println(list);
    }
}

conocimiento gasolinera

1. Ver el código fuente de este método en IDEA.

Si presiona CTRL+B en IDEA para ver la interfaz de este método

imagen-20230425111615513

Luego podemos seleccionar el método y ver el método de implementación.

imagen-20230425111652280

2. Teclas de acceso directo del código del paquete en IDEA

Si usa las teclas de método abreviado CTRL+ALT+T en IDEA para ajustar el código

imagen-20230426114136309

3. Extraer claves de acceso directo de código en IDEA

Ctrl+Alt+M

imagen-20230429114159940

4. Métodos de extensión de manejo de excepciones en Java.

imagen-20230427091534645

5. La diferencia entre StringBuider y StringBuffer

imagen-20230429111344077

imagen-20230429111407230

ilustrar:

Los métodos de StringBuider y StringBuffer en Java son los mismos, la diferencia es que StringBuffer agrega un método de sincronización para cada método, de modo que al operar métodos, solo se garantiza el funcionamiento de un método, mejorando así la seguridad del código.

Reponer:

Si es solo un subproceso, use StringBuider. Si en un entorno de subprocesos múltiples, se debe considerar la seguridad del subproceso, use StringBuffer8

6.Clase de herramienta de matriz de matrices

imagen-20230321135006240

En Java, Arraysuna clase que proporciona muchos métodos estáticos útiles que se pueden utilizar para manipular y procesar matrices.

A continuación se muestran Arraysalgunos usos comunes de las clases:

  1. Arrays.toString()Método: se utiliza para convertir una matriz en una cadena.
  2. Arrays.sort()Método: se utiliza para ordenar la matriz en orden ascendente.
  3. Arrays.copyOf()Método: se utiliza para copiar una matriz.
  4. Arrays.binarySearch()Método: se utiliza para buscar un elemento específico en una matriz ordenada.
  5. Arrays.fill()Método: se utiliza para establecer todos los elementos de la matriz en el valor especificado.
  6. Arrays.equals()Método: se utiliza para comparar la igualdad de dos matrices.
  7. Arrays.asList()Método: se utiliza para convertir una matriz en una lista.

Es importante tener en cuenta que Arraysla mayoría de los métodos de una clase son métodos estáticos, por lo que no es necesario crear Arraysun objeto para llamarlos. Además, Arrayslos métodos de la clase se aplican a matrices de todos los tipos de datos básicos, así como a matrices de objetos.

Supongo que te gusta

Origin blog.csdn.net/D_boj/article/details/132257791
Recomendado
Clasificación