Study Notes: Dark Horse Programmer Java-Advanced Chapter (1) (Part 4)

Java language introduction to mastery chapters

  1. Study notes: Java-Basics (Part 1)_ljtxy.love’s blog-CSDN blog
  2. Study Notes: Java-Intermediate (Part 2)_ljtxy.love’s Blog-CSDN Blog
  3. Study Notes: Java-Advanced Chapter (Part 3)_ljtxy.love’s Blog-CSDN Blog
  4. Study Notes: Java-Advanced Chapter (1) (Part 4)_ljtxy.love's Blog-CSDN Blog
  5. Study Notes: Java-Advanced Chapter (2) (Part 5)_ljtxy.love’s Blog-CSDN Blog
  6. Study Notes: New Features of Java8_ljtxy.love’s Blog-CSDN Blog

Article directory

20.Stream stream

Summary of notes:

  1. Overview: In Java 8, Stream is a mechanism for processing collections . It can perform various operations on collections ( filtering , mapping , sorting, etc.) and generate new collections, while supporting parallel processing.

  2. Function: Combining Lambda expressions to simplify the operation of collections and arrays

  3. Steps for usage:

    1. Get Stream stream object

      • Collection system collection: use the default method stream() to generate a stream, default Stream stream()

      • Map system collection: Convert Map into Set collection and indirectly generate streams

      • Array: Generate a stream through the static method stream in the Arrays tool class

      • Multiple scattered data of the same data type: generate a stream through the static method of(T... values) of the Stream interface

    2. Use intermediate methods to process data

      • filter : filter

        list.stream().filter(new Predicate<String>() {
                   
                   
            @Override
            public boolean test(String s) {
                   
                   
                return s.startsWith("张");
            }
        })
        
      • limit : Get the first few elements

        list.stream().limit(3)
        
      • skip : skip the first few elements

        list.stream().skip(2)
        
      • distinct : Element deduplication , (note that when using a custom object for deduplication, it depends on the hashCode and equals methods)

        list1.stream().distinct()
        
      • concat : merge two streams a and b into one stream

        Stream.concat(list1.stream(),list2.stream())
        //注意:在使用时,此处使用Stream对象中的concat静态方法
        
      • map : convert data types in the stream

        // 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. Use finalizers to process data

      • forEach : Traverse

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

        list.stream().count();
        
      • toArray : Collect data from the stream and put it into an array

        list.stream().toArray(new IntFunction<String[]>() {
                   
                   
            @Override
            public String[] apply(int value) {
                   
                   
                return new String[value];
            }
        });
        
        System.out.println(Arrays.toString(arr));
        
      • collect : Collect data in the stream and put it into a collection

        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 Overview

20.1.1 Definition

In Java 8, Stream is a mechanism for processing collections. It can perform various operations on collections (filtering, mapping, sorting, etc.) and generate new collections, while supporting parallel processing.

​ Simply put, a Stream is a container that can be processed multiple times, and elements can be converted and processed through some chain operations. Stream operations are divided into intermediate operations and end operations. The intermediate operation returns another stream, and the end operation returns not a stream, but a calculation result.

​ Using Stream can simplify code implementation, and due to its parallel processing capabilities, it can greatly improve code running efficiency.

20.1.2 Thoughts

image-20230425102635610

illustrate:

Filter layer by layer to finally get the desired results

20.1.3 Usage steps

  • Get Stream stream
    • Create a pipeline and put data on the pipeline to prepare for operation
  • middle way
    • Operations on the assembly line
    • After one operation is completed, you can continue to perform other operations
  • final method
    • A Stream can only have one finalizer
    • Is the last operation on the pipeline

20.2 Function

The main function of Stream is to perform set operations and functional programming on data, which can achieve efficient data screening, sorting, filtering, grouping, statistics and other operations.

20.3 Get the stream

image-20230425102937415

method of obtaining:

  • Collection system collection: use the default method stream() to generate a stream, default Stream stream()

  • Map system collection: Convert Map into Set collection and indirectly generate streams

  • Array: Generating a stream via the static method stream in Arrays

  • Multiple data of the same data type: generate a stream through the static method of(T... values) of the Stream interface

Sample code:

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);
    }
}

illustrate:

In collections , single-column collections can obtain the Stream stream through the .stream() method. Double-column collections can be converted to single-column collections first and then retrieved.

In an array, the Stream stream can be obtained through the .stream() method of the Arrays tool class

In scattered data , the Stream stream can be obtained through the Stream.of() method.

Note that the scattered data needs to be of the same data type and the parameter type in Stream.of() must be a reference data type. If it is a basic data type, the automatic boxing operation will not be completed, but the entire basic data will be Type is treated as an element

20.4 Intermediate methods

image-20230425104642136

20.4.1filter()

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.2limit()

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

20.4.3skip()

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

20.4.4distinct()

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

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

illustrate:

The bottom layer of the distinct() method is new HashSet, and HashSet needs to rely on the equals and hashCode methods for deduplication.

image-20230425113033366

Notice:

If you need to deduplicate custom objects, you need to override the equals and hashCode methods.

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.5map()

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));

Description: underlying source code

image-20230425114353100

Notice:

  • Intermediate method, returns a new Stream. The original Stream can only be used once (the stream will be automatically closed after being used once). It is recommended to use chain programming.
  • Modifying the data in the Stream will not affect the data in the original collection or array.

20.5 Termination method

image-20230425114628959

20.5.1forEach()

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));

illustrate:

image-20230425160329430

20.5.2count()

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

illustrate:

The return value of the .count() method is of type int, so after the call is completed, the Stream will terminate.

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));

illustrate:

  • The role of the parameters of the toArray method: responsible for creating an array of the specified type
  • The bottom layer of the toArray method will get each data in the stream in turn and put the data into the array.
  • The return value of the toArray method: is an array containing all the data in the stream

detail:

  • Question: String[] arr2, a string array, prints out the address value.
  • Reason: When printing reference type objects in Java, the toString() method in Java will be used by default. The toString() method is used to print the address value.
  • Solution: You can rewrite the toString() method at this time, or use the toString method in the Arrays tool class
  • Supplement: Arrays.toString method will help us rewrite the toString method in java

20.5.4collect()

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}

illustrate:

The collect method cooperates with the tool class Collectors.toList or Collectors.toSet or Collectors.toMap method to complete the data acquisition of the Stream stream.

21.Method reference

Summary of notes:

  1. Overview:

    1. Meaning: Take the existing method and use it as the method body of the abstract method in the functional interface

    2. rule:

      • The reference must be a functional interface
      • The referenced method must already exist
      • The formal parameters and return value of the referenced method need to be consistent with the abstract method
      • The function of the referenced method must meet the current needs
    3. Quote: ::(two consecutive colons)

  2. Function: Method references can make the code more concise and easy to understand, and improve the readability and maintainability of the code. Avoid unnecessary repeated calls in Lambda expressions .

  3. Classification:

    • To reference a static method :

      /*格式:
      	类::方法名*/
      list.stream().map(Integer::parseInt).forEach(s-> System.out.println(s));
      
    • Referencing member methods :

      • other classes

        /* 格式:
        	new对象::方法名*/
        list.stream().filter(new stringOpration()::stringJudge)
        
      • This category

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

        Details: If this method is used in a static method, a new object is required because there is no this in the static method

      • parent class

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

        Details: No super keyword in method reference

    • Reference constructor :

      /*格式:
      	类名::new */
      List<Student> newList2 = list.stream().map(Student::new)
      
    • Class name refers to member method :

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

      Note: Difference from reference member method

      • One is an object reference , and all methods in the class can be used ;
      • This is referenced by the class name , and its parameters need to correspond to the first parameter type in the abstract method.
    • The construction method of the reference array :

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

21.1 Overview

21.1.1 Definition

In Java, a method reference is a special Lambda expression that is used to simplify the writing of Lambda expressions, especially when the Lambda expression only calls an existing method.

21.1.2 Rules

  • The reference must be a functional interface
  • The method referenced must already exist
  • The formal parameters and return value of the referenced method need to be consistent with the abstract method
  • The function of the referenced method must meet the current needs

21.1.3 Method reference characters

: : This symbol is a reference operator, and the expression in which it is located is called a method reference.
: means:
  • method reference

Sample code:

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 Classification

  1. referencing a static method
  2. reference member method
  3. reference constructor
  4. Class name refers to member method
  5. Reference array constructor

21.2 Function

​ It uses the method as an object instead of directly defining an anonymous method like a Lambda expression.

Method references can make the code more concise and easy to understand, and improve the readability and maintainability of the code. In addition, method references can also be used to improve the performance of your code because it avoids unnecessary repeated calls in lambda expressions .

image-20230812092547466

illustrate:

Here is the difference between method references

21.3 Reference static methods

Format:

::方法名

Example:

//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));

illustrate:

When the required method parameters already exist, you can call them based on "class name::method name"

21.4 Reference member methods

Format:

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

Example (other classes):

/* 格式:
	其他类:其他类对象::方法名*/
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;
    }
}

illustrate:

Call by calling the method name of other class objects

Example (this category):

/* 格式:
	本类: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;
    }
}

detail:

In the static method, there is no this, so you need to call the new object of this class.

Example (parent class):

/* 格式:
	父类: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));
    }
}

illustrate:

If this class FunctionDemo3 has a parent class, it can be called through the super method name.

21.5 Reference constructor

/*格式:
	类名::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);

illustrate:

At this time, by performing new through the Student class name, the Student's constructor can be called.

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]);
    }
}

illustrate:

At this time, the formal parameters and return values ​​in the Student class object need to be consistent with the abstract method.

nitty gritty:

At this time, the return value of the constructor method defaults to returning the entire Student class object.

21.6 Class name refers to member method

/*格式:
	类名::成员方法 */
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));*/
}

Note: Difference from reference member method

All member methods in the class cannot be referenced . If the first parameter of the abstract method is of type A, only methods in class A can be referenced.

21.7Constructor method of reference array

/*格式:
	数据类型[]::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.Exception handling

Summary of notes:

  1. Overview

    • Exception: refers to an abnormal situation that occurs during the execution of the program , which will eventually cause the JVM to stop abnormally .
    • Unusual architecture

    image-20230812093622894

    • Anomaly classification

      1. Compile-time exceptions : Except for RuntimeExcpetion and its subclasses, all others are compile-time exceptions. It needs to be processed during the compilation phase, and its function is to remind the programmer.
      2. Runtime exception : RuntimeException itself and all subclasses are runtime exceptions. No error is reported during the compilation phase, it occurs when the program is running.
    • abnormal mechanism

      • Output the name of the exception, the cause of the exception, and the location where the exception occurred on the console
      • The program stops execution and the code below the exception will no longer be executed .
  2. abnormal effects

    • Exception is the key reference information used to query bugs
    • Exceptions can be used as a special return value within a method to notify the caller of the underlying execution status.
  3. catch exception

    • Format

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

    image-20230426111351928

  5. Exception method

    image-20230426111823569
  6. Throw an exception

    • Declare exception throws keyword
    • throw exception throw keyword
  7. Custom exception:

    • Define exception class

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

      illustrate:

      1. Exception name ends with Exception
      2. Exception class inherits Exception
      3. Exception classes can generate no-parameter, with-parameter, and empty-parameter construction methods for detailed description
  8. Final execution: finally keyword

22.1 Overview

22.1.1 Definition

The meaning of exception refers to the abnormal situation that occurs during the execution of the program, which will eventually cause the JVM to stop abnormally.

22.1.2 Abnormal system

​ The exception mechanism actually helps us find problems in the program. The root class of exception is , and there are two java.lang.Throwablesubclasses under it:java.lang.Errorjava.lang.Exceptionjava.lang.Exception

image-20230426102346006

  • Error: Represents a system-level error (a serious problem). Once a problem occurs in the system, Sun will encapsulate these errors into an Error object. Error is for the sun company itself, not for our programmers. So we developers don't have to worry about it.
  • Exception: It is called an exception and represents a problem that may occur in the program. We usually use Exception and its subclasses to encapsulate the problems that arise in the program.
  • Runtime exceptions: RuntimeException and its subclasses, no exception reminder will appear during the compilation phase. Exceptions that occur during runtime (such as array index out-of-bounds exception)
  • Compile-time exception: Exception reminders will appear during the compilation phase. (For example: date parsing exception)

22.1.3 Anomaly classification

image-20230426103246556

  • Compile time exception : checked exception. During compilation, it will be checked, and if no exception is handled, the compilation will fail. (such as abnormal date formatting)
  • Runtime exception : runtime exception. During runtime, exceptions are checked. During compile time, runtime exceptions are not detected by the compiler (no errors are reported). (such as mathematical anomalies)

22.1.5 Exception handling mechanism

The default way the JVM handles exceptions

  1. Output the name of the exception, the cause of the exception, and the location where the exception occurred on the console
  2. The program stops execution and the code below the exception will no longer be executed .

Example:

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

Printing effect:image-20230426105516747

22.2 Function

effect:

  • Exception is the key reference information used to query bugs

    image-20230426104428716

  • Exceptions can be used as a special return value within a method to notify the caller of the underlying execution status.

    image-20230426104523278

    illustrate:

​ Simply put, it throws an exception

22.3Exception catching

The try-catch method is to catch exceptions.

illustrate:

  • **try:** Code that may generate exceptions is written in this code block.
  • **catch:** is used to capture certain exceptions and handle the captured exceptions.
  • Catch exceptions : In Java, the targeted statements for exceptions are captured, and the exceptions that occur can be handled in a specified way.

Notice:

​ Neither try nor catch can be used alone, they must be used together.

Basic use case

/* 格式:
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 Frequently Asked Questions about Exception Handling

image-20230426111351928

  1. If no problem is encountered in try, how to execute it?

    • All codes in try will be executed, and the code in catch will not be executed.

       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. If multiple problems may be encountered in try, how to execute them?

    • Will write multiple catches corresponding to them

      //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("看看我执行了吗?");
      

      detail:

      If we want to catch multiple exceptions, if there is a parent-child relationship among these exceptions, then the parent class must be written below

      Replenish:

      After JDK7, we can catch multiple exceptions at the same time in catch, separated by |

  3. If the problem encountered in try is not caught, how to execute it?

    • The code equivalent to try...catch is written in vain, and will eventually be handed over to the virtual machine for processing.

      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. If a problem is encountered in try, will other codes below try still be executed?

    • The following code will not be executed. It will jump directly to the corresponding catch and execute the statement body in the catch. But if there is no corresponding catch to match it, it will still be handed over to the virtual machine for processing.

      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 Commonly used methods for exceptions

image-20230426111823569

22.5.1getMessage()

// 返回此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.2toString()

// 返回此可抛出的简短描述
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.3printStackTrace()

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

image-20230426141848634

22.6 Exception throwing handling

Exception handling:

  • Compile-time exception throws
  • Runtime exception throw

22.6.1 Declaring exception throws keyword

Notice:

Written at the method definition, it means declaring an exception and telling the caller what exceptions may occur when using this method.

Format:

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

22.6.2 Throw exception throw keyword

Notice:

​ Write in the method, end the method, manually throw the exception object, and hand it over to the caller. The following code in the method will no longer be executed

Format:

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

22.7 Custom exceptions

22.7.1 Overview

Meaning: Define exception classes according to the exceptions of your own business during development

22.7.2 Usage steps

1. Define exception classes

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

illustrate:

Usually, the class name is named xxxException and ends with Exception. At the same time, it is best to know the name of the class name

2. Write inheritance relationship

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

illustrate:

If this custom exception is used for compile-time exceptions, inherit Exception

If this custom exception is used for runtime exceptions, it inherits RuntimeException

3. Empty parameter structure

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

illustrate:

Usually implement the empty parameter construction and the construction method with parameters

4.Construction with parameters

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

illustrate:

The purpose of constructing with parameters is to better describe the error message

22.8 Final execution

In Java, finally is a keyword used to define code that must be executed in a try-catch code block. Regardless of whether an exception is thrown in the try block, the finally block will be executed.

Format:

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

detail

When the relevant method to exit the JVM is called only in try or catch, finally will not be executed, otherwise finally will always be executed.

Example

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

23.File class

Summary of notes:

  1. Overview:

    1. Meaning: java.io.FileClasses are abstract representations of file and directory pathnames
    2. Path: absolute path and relative path
  2. Function: Used to operate files and directories, such as creating , deleting , and obtaining file information. Note that the File class cannot obtain the detailed content in the file !

  3. Construction method:

    image-20230426155428093
  4. Common member methods

    1. Judgment and acquisition: isDirectory (), isFIle (), exists (), length (), getAbsolutePath (), getPath (), getName (), lastModified ()
    2. Create, delete: createNewFile (), mkdir (), mkdirs (), delete ()
    3. Get and traverse: ListFiles () (emphasis)

23.1 Overview

23.1.1 Definition

​Classjava.io.File is an abstract representation of file and directory path names, mainly used for operations such as creation, search, and deletion of files and directories.

23.1.2 Path

image-20230426155057941

23.2 Function

The File class in Java is a class used to represent files or directories . It can be used to operate files or directories , such as creating, reading, writing, deleting and other operations.

The File class is part of the Java I/O library. It provides a variety of methods to obtain information about files and directories, such as file name, path, size, modification time, etc.

The File class can also be used for file and directory traversal, as well as file and directory filtering. It is one of the classes commonly used in Java programs

23.3Construction method

image-20230426155428093

Example:

// 文件路径名
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);

tips:

  1. A File object represents a file or directory that actually exists on the hard disk.
  2. Regardless of whether there is a file or directory in the path, it does not affect the creation of the File object.

23.4 Common member methods

23.4.1 Judgment and acquisition

image-20230426160104422

Example:

23.4.1.1isDirectory()、isFIle()、exists()

//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.2length()

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);

detail:

  • This method can only get the size of the file , in bytes. If our unit is M or G, we can continue to divide by 1024
  • This method cannot get the size of the folder. If we want to get the size of a folder, we need to add up the sizes of all the files in the folder.

23.4.1.3getAbsolutePath()

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.5getName()

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

detail:

  • When this method obtains the name of the file
  • When this method obtains the name of the folder

23.4.1.6lastModified()

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

23.4.2Create, delete

image-20230426163941377

Notice:

The delete method can only delete files and empty folders by default. The delete method directly deletes files without going to the recycle bin.

23.4.2.1createNewFile()

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

detail:

  • Create a file
    • If the file represented by the current path does not exist, the creation is successful and the method returns true
    • If the file represented by the current path exists, the creation fails and the method returns false.
  • If the parent path does not exist, the method will have an exception IOException
  • The createNewFile method must create a file. If the path does not contain a suffix name, a file without a suffix will be created.

23.4.2.2mkdir()

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

detail:

  • The path is unique in Windows. If the current path already exists, the creation fails and false is returned.
  • The mkdir method can only create single-level folders and cannot create multi-level folders.

23.4.2.3mkdirs()

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

detail:

  • You can create both single-level and multi-level folders

23.4.2.4delete()

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

detail:

  • If you delete a file, delete it directly without going to the Recycle Bin.
  • If you delete a folder
    1. If the folder is empty, delete it directly without going to the Recycle Bin.
    2. Delete fails if the folder has content

23.4.3 Fetching and traversing

image-20230426212031932

23.4.3.1listRoots()

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

23.4.3.2list()

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

23.4.3.3list(FilenameFilter filter)

//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() (master)

//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);
    }
}

Notice:

  • When the path represented by the caller's File does not exist, null is returned.
  • When the path represented by the caller File is a file, null is returned
  • When the path represented by the caller's File is an empty folder, an array of length 0 is returned.
  • When the path represented by the caller's File is a folder with content, the paths of all files and folders inside are placed in the File array and returned
  • When the path represented by the caller's File is a folder with hidden files, put the paths of all files and folders in the File array and return it, including hidden files. When the path represented by the caller's File is a file that requires permission to access. When clipping, returns null

23.4.3.6listFiles(FileFilter filter)

//创建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(FilenameFilter filter)

//调用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.IO stream

Summary of notes: see each section

24.1 Overview

Summary of notes:

  1. Definition: IO refers to input and output operations on files

  2. Classification:

    • Input stream, output stream: reading data and writing data
    • Byte stream, character stream: any binary file and processing characters . The underlying transmission is always binary data

    image-20230812095212381

  3. Streaming architecture:

    image-20230812095223902

  4. Use the IO flow principle: create as you use

24.1.1 Definition

​ I/O operations in Java mainly refer to using java.iothe content under the package to perform input and output operations. Input is also called reading data, and output is also called writing data.

​ IO streams in Java refer to a set of classes and interfaces used to handle input and output operations, allowing programs to read and write data and interact with files, networks, and other devices.

24.1.2 Classification

image-20230427075443583

24.1.3 Input stream and output stream

  • input stream:

    In IO streams in Java, the input stream is the stream used to read data . Input streams can read data from various data sources such as files, network connections, and standard input.

    image-20230427141537602

  • Output stream:

    In Java's IO stream, the output stream refers to the stream that writes data from the program to the outside . Output streams are usually used to write data in the program to files, network connections, pipes, etc.image-20230427141749753

24.1.4 Byte stream and character stream

  • byte stream

    ​ All file data (text, pictures, videos, etc.) are stored in the form of binary numbers , one byte at a time, and the same is true during transmission. Therefore, byte streams can transmit arbitrary file data . When operating streams, we must always be clear that no matter what stream object is used, the underlying transmission is always binary data .

    image-20230427142208211

  • character stream

    In the IO stream in Java, a character stream is an IO stream that processes character data, that is, a stream that reads or writes data by character. Unlike byte streams, character streams are processed according to characters (Unicode codes)

    image-20230427142233684

24.1.5 Fluid systems

image-20230504084825259

24.2-byte elementary stream

Summary of notes:

  1. Overview:

    • Definition: Read byte stream data from a file

    • Architecture:

      image-20230812102521292

  2. Construction method:

    1. Input stream:
      • FileInputStream(File file)
      • FileInputStream(String name)
    2. output stream:
      • FileOutputStream(File file)
      • FileOutputStream(String name)
  3. Common member methods:

    1. input stream:

      • read()
      • read(byte[] b)
      • close()
    2. Output stream:

      • write(int b)

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

  4. principle:

    1. Create channel

      FileInputStream fis = new FileInputStream();
      FileOutputStream fos = new FileOutputStream("myio\\a.txt");
      
    2. Data processing

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

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

24.2.1 Input stream-FileIntputStream

24.2.1.1 Overview

​IsFileInputStream the class used to read file data in the Java IO library, used to read byte stream data from the file.

24.2.1.2 Basic use cases

//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();

tips:

read() method, every time a data is read, the pointer will be moved once

24.2.1.3Construction method

  • FileInputStream(File file): Creates a FileInputStream by opening a connection to an actual file named by the File object file in the file system.
  • FileInputStream(String name): Creates a FileInputStream by opening a connection to an actual file named by the pathname in the file system.
24.2.1.3.1FileInputStream(File file)
/* 格式:
	public FileInputStream(File file) */
// 使用File对象创建流对象
File file = new File("a.txt");
FileInputStream fos = new FileInputStream(file);

detail:

​ If the file does not exist, an error will be reported directly. Because the created file has no data and has no meaning. Therefore, Java has not designed such meaningless logic. If the file does not exist, an error will be reported directly.

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

detail:

Same as above

24.2.1.4 Common member methods

image-20230427150251847

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

detail:

  • Read one byte at a time, and what is read is the number corresponding to the data on ASClI.
  • The end of the file has been read, and the read method returns -1.
24.2.1.4.2read(byte[] b)
/* 格式:
	FileInputStream对象.raad(byte[] b)
   作用:一次读取一个字节数组数据 */
byte[] b = new byte[2];
int len= fis.read(b)

tips:

Using array reading to read multiple bytes at a time reduces the number of IO operations between systems, thereby improving the efficiency of reading and writing.

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

illustrate:

Remove resource hog

24.2.1.5 Reading multiple bytes at once

//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();

illustrate:

image-20230427150810725

  • At this time, each read will put the bytes read from the file into the byte array.
  • When the last byte is read, only the first number in the array will be overwritten, so the last read data will remain in the data.
  • Now through new String (byte stream array, index, length), this String construction method can reasonably avoid this reading problem.

24.2.1.6 Loop reading

//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 Principle

How input streams work

image-20230427084525131

illustrate:

FileInputStream fis = new FileInputStream();

image-20230427084537691

illustrate:

int b1 = fis.read();

image-20230427084558787

illustrate:

fis.close();

24.3.2 Output stream-FileOutputStream

24.3.2.1 Overview

​It isFileOutputStream a class in the Java I/O package, also called byte output stream. Byte output stream used to operate local files. Data in the program can be written to local files.

24.3.2.2 Basic use cases

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

24.3.2.3Construction method

  • public FileOutputStream(File file):Creates a file output stream to write to the file represented by the specified File object.
  • public FileOutputStream(String name): Creates a file output stream to write to the file with the specified name.
24.3.2.3.1FileOutputStream(File file)
/* 格式:
	public FileOutputStream(File file) */
// 使用File对象创建流对象
File file = new File("a.txt");
FileOutputStream fos = new FileOutputStream(file);

detail:

  • If the file does not exist, a new file will be created, but the parent path must exist.
  • If the file already exists, the file will be cleared
24.3.2.3.2FileOutputStream(String name)
/* 格式:
	public FileOutputStream(File file) 
	作用:使用文件名称创建流对象*/
FileOutputStream fos = new FileOutputStream("b.txt");

24.3.1.4 Common member methods

image-20230427081442801

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

detail:

The parameter of the write method is an integer, but what is actually written to the local file is the ASCII character corresponding to the integer.

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

illustrate:

Using array writing, multiple bytes are written each time, which reduces the number of IO operations between systems, thereby improving the efficiency of reading and writing.

24.3.1.4.3write(byte[] b, int off, 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.4close()
/* 格式:
	FileOutputStream对象.close()
   作用:释放资源 */
fis.close();

illustrate:

Resources must be released after each use of the stream

24.3.1.5 Line breaks and continuations

//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();

tips:

  1. Write on a new line:
    • Just write out a newline again
    • windows: \r\n
    • Linux: \n
    • Mac: \r
  2. detail:
    • In the Windows operating system, Java has optimized carriage return and line feed.
    • Although the complete one is \r\n, we write one of them \r or \n,
    • Java can also implement line breaks, because Java will complete it under the hood.
  3. Continuation:
    • If you want to continue writing, just turn on the continue writing switch.
    • Switch position: the second parameter of the created object
    • Default false: indicates that continuation is turned off. Creating an object at this time will clear the file.
    • Passing true manually means turning on continuation, and creating an object at this time will not clear the file.

24.3.1.3 Principle

How output streams work

image-20230427080347014

illustrate:

Generate a channel for data transmission through the new method

image-20230427080419743

illustrate:

Data transmission through write method

image-20230427080505671

illustrate:

Destroy the data transmission channel through the close method

24.3.3 Case – File copy

//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();

tips:

The closing principle of the flow: open first and then close, and then open and then close.

Disadvantages:

image-20230427085941843

illustrate:

If large files are read, it will be very slow.

//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();

illustrate:

At this time, using arrays for reading and writing can reduce the number of IO operations between systems, thereby improving the efficiency of reading and writing.

24.3 Character elementary stream

Summary of notes:

  1. Overview:

    • Meaning: Read character data from a file

    • Architecture:

      image-20230812102704912

  2. Construction method:

    1. input stream:

      • FileReader(File file)
      • FileReader(String fileName)
    2. Output stream:

      • FileWriter(File file)
      • FileWriter(String pathName)
  3. Member methods:

    1. input stream:

      • read()
      • read(char[] cbuf)
    2. Output stream:

      • write(int/string c)
      • write(char[] cbuf)
      • write(char[] cbuf, int off, int len)
      • flush()
  4. Principle: After the bottom layer reads the data, it will save part of the data in 4 bytes in the buffer , which is convenient for reading and speeds up reading and writing.

Features:

  • Input stream: read one byte at a time, when encountering Chinese, read multiple bytes at a time
  • Output stream: The bottom layer will encode the data according to the specified encoding method, turn it into bytes and then write it to the file.

Character encoding: the correspondence rules between bytes and characters. The default Chinese encoding for Windows systems is the GBK encoding table. The encoding in IDEA defaults to the UTF-8 encoding table

24.3.1 Input stream-FileReader

24.3.1.1 Overview

​IsFileReader a class in the Java I/O package used to read character data from files. Its function is to convert the character input stream into a byte input stream and read the character data in the file. It is often used to read text files.

24.3.1.2 Basic use cases

//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.3Construction method

  • FileReader(File file): Creates a new FileReader, given the File object to be read.
  • FileReader(String fileName): Creates a new FileReader, given the name of the file to be read.
24.3.1.3.1FileReader(File file)
/* 格式:
	public FileReader(File file) 
	作用:使用File对象创建流对象*/
File file = new File("a.txt");
FileReader fr = new FileReader(file);
24.3.1.3.2FileReader(String fileName)
/* 格式:
	public FileReader(File file) 
	作用:使用文件名称创建流对象*/
FileReader fr = new FileReader("b.txt");

24.3.1.4 Common member methods

  • readMethod, you can read data one character at a time, promote it to int type, read to the end of the file, and return-1
  • read(char[] cbuf), each time the length of b is read into the array, the number of valid characters read is returned. When the end of the read is reached, the number of valid characters is returned.-1
24.3.1.4.1read()
/* 格式:
	FileReader对象.read()
	作用:每次可以读取一个字符的数据*/
int b = fr.read())

illustrate:

Every time a character is read, it will be automatically promoted to int type, so casting is required to get the data.

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

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

illustrate:

The three steps of reading data, decoding, and forced conversion are merged, and the characters after forced conversion are put into the array

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

illustrate:

Remove resource hog

24.3.1.5 Loop reading

Loop – single character reading

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

Loop – character array reading

// 使用文件名称创建流对象
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 Principle

The underlying principle of character input stream

image-20230427103636695

illustrate:

image-20230427103809065

image-20230427104056436

illustrate:

When the code is executed, breakpoint debugging can be

Example

 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 Output stream-FileWriter

24.3.2.1 Overview

The abstractjava.io.Writer class is the super class that represents all classes used to write out character streams, writing out specified character information to the destination. It defines the basic common functional methods of byte output streams

24.3.2.2 Basic use cases

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

24.3.2.3Construction method

image-20230427100417262

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

detail:

  • If the file does not exist, a new file will be created, but the parent path must exist.
  • If the file already exists, the file will be cleared. If you don’t want to clear it, you can turn on the continuation switch.
24.3.2.3.2FileWriter(String pathName)
/* 格式:
	public FileWriter(File file)
	作用:使用文件名称创建流对象*/

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

detail:

Same as above

24.3.2.4 Common member methods

image-20230427100521001

image-20230427105116231

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

Notice:

  • The close method is not called, the data is only saved in the buffer and is not written out to the file.
  • If the parameter of the write method is an integer, but what is actually written to the local file is the character corresponding to the integer in the character set
24.3.2.3.4write(char[] cbuf)
/* 格式:
	FileWriter对象.write(char[] cbuf)
	作用:写出一个字符数组*/
char[] chars = "黑马程序员".toCharArray();
fw.write(chars); // 黑马程序员
24.3.2.3.5write(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.6flush()
/* 格式:
	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();
    }
}

Notice:

Even if the flush method writes the data, the close method must be called at the end of the operation to release system resources.

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

illustrate:

Remove resource hog

24.3.2.5 Continuation and newline

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();
    }
}
输出结果:
黑马
程序员

illustrate:

Manually write line breaks in the program

24.3.2.6 Principle

The output stream principle of character basic stream

image-20230427105006872

illustrate:

  • When writing data, Java will first write the data into the memory cache.
  • When the buffer length is full of 8192 bytes, it will be automatically written to the file
  • When the IO stream is closed, the content in the buffer area will also be automatically written to the file

24.4 character set

Summary of notes:

  1. Definition: is a method of mapping characters in a character set to one or more numbers
  2. Reasons for garbled characters: reading data , not reading the entire data, and the character set method when decoding and encoding is not uniform.
  3. Encoding and decoding in Java:
    • GBK encoding uses two bytes to store a Chinese character
    • UTF-8 encoding uses three bytes to store a Chinese character

24.4.1 Definition

Character set (Character set) is a method of mapping characters in a character set to one or more numbers.

image-20230427093521471

image-20230427093511799

24.4.2 Causes of Garbled Codes

image-20230427092438753

image-20230427092605878

image-20230427092531144

24.4.3 Encoding and decoding in Java

image-20230427093209309

Example:

//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);

illustrate:

  • GBK encoding uses two bytes to store a Chinese character
  • UTF-8 encoding uses three bytes to store a Chinese character

24.4 Buffered streams

Summary of notes:

  1. Overview: Buffered streams, also called efficient streams , are FileXxx enhancements to four basic streams . They wrap basic streams into advanced streams to improve the performance of reading/writing data.

  2. Byte buffer stream:

    • Input stream BufferedInputStream :

      // 1.创建流对象
      BufferedInputStream bis = new BufferedInputStream(new FileInputStream("jdk9.exe"));
      // 2.读取数据
      int b = bis.read();
      // 3.关闭资源
      bis.close();
      
    • Output stream 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. character buffer stream

    • Input stream BufferedReader

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

      // 1.创建流对象
      BufferedWriter bw = new BufferedWriter(new FileWriter("out.txt"));
      // 2.写出数据
      bw.write("黑马");
      // 3.写出换行
      bw.newLine();
      // 4.关闭资源
      bw.close();
      
  4. The underlying principle: the efficiency of buffer adjustment is to open up an area in memory and name it buffer . The function of the buffer reduces the frequent reading and writing of memory and hard disk , thereby improving the reading and writing efficiency of the hard disk area.

    image-20230812104312395

24.4.1 Overview

24.4.1.1Definition

​ Buffer streams, also known as high-efficiency streams, are enhancements to the four basic FileXxxstreams, packaging basic streams into advanced streams, and improving the performance of reading/writing data.

Classified according to data type:

  • Byte buffer stream : BufferedInputStream,BufferedOutputStream
  • Character buffer stream : BufferedReader,BufferedWriter

24.4.4.2 Architecture

image-20230427112305233

24.4.2 Byte Buffered Stream

24.4.2.1 Input stream-BufferedInputStream

24.4.2.1.1 Overview

BufferedInputStreamIt is an input stream class provided by the Java I/O library. It uses an internal buffer to improve the efficiency of reading files.

24.4.2.1.2 Basic use cases
// 1.创建流对象
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("jdk9.exe"));
// 2.读取数据
int b = bis.read();
// 3.关闭资源
bis.close();
24.4.2.1.3Construction method
  • public BufferedInputStream(InputStream in): Create a new buffered input stream.
/* 格式:
	public BufferedInputStream(InputStream in)
    作用:创建字节缓冲输入流*/
// 创建字节缓冲输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bis.txt"));

illustrate:

image-20230427114025839

  • When using this constructor, Java will perform a new array under the hood with a length of 8192 bytes.
24.4.2.1.4 Common member methods

Please refer to the input stream of byte elementary stream

24.4.2.2 Output stream-BufferedOutputStream

24.4.2.2.1 Overview
24.4.2.2.2 Basic use cases
// 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.3Construction method
/* 格式:
	public BufferedOutputStream(OutputStream os)
    作用:创建字节缓冲输出流对象*/
 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myio\\a.txt"));

illustrate:

image-20230427114223961

  • When using this constructor, Java will perform a new array under the hood with a length of 8192 bytes.
24.4.2.2.4 Common member methods

Please refer to the output stream of byte elementary stream

24.4.2.3 Case – File Copy

// 方式一:
//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();

tips:

​ When using a buffered stream to create an object, you only need to release the resources of the buffered stream object, and do not need to release the resources of the file input and output stream objects. Because Java will perform automatic shutdown operations at the bottom level

image-20230427114552934

24.4.4.4 Principle

High efficiency principle of byte buffer stream

image-20230427134512840

illustrate:

​ To increase the efficiency of the buffer, an area is opened in the memory and named the buffer. The function of the buffer reduces the frequent reading and writing of memory and hard disk, thereby improving the reading and writing efficiency of the hard disk area.

image-20230427134445862

illustrate:

​ When reading and writing data by defining an array, it actually speeds up the frequent reading and writing of data in the memory, thereby improving the reading and writing efficiency of the memory area.

24.4.3 Character buffer stream

24.4.3.1 Input stream-BufferedReader

24.4.3.1.1 Overview

​IsBufferedReader a character buffer input stream in Java, which can provide a method to read one or more lines of text data at a time, and can ensure the sequential reading of the input stream.

24.4.3.1.2 Basic use cases
// 1.创建流对象
BufferedReader br = new BufferedReader(new FileReader("in.txt"));
// 2.读取数据
String line = bis.readLine();
// 3.关闭资源
br.close();
24.4.3.1.3Construction method
/* 格式:
	public BufferedReader(Reader in) 
	作用:创建字符缓冲输入流对象*/
// 示例
BufferedReader br = new BufferedReader(new FileReader("br.txt"));
24.4.3.1.4 Common member methods
  • public String readLine(): Read a line of text.
  • For other common methods, see Character Basic Input Stream
24.4.3.1.4.1readLine()
/* 格式:
	BufferedReader对象.readLine()
	作用:每次可以读取一个字符的数据*/
 String line = br.readLine()

24.4.3.2 Output stream-BufferedWriter

24.4.3.2.1 Overview

​It isBufferedWriter a character output stream in Java IO. It is used to write text data into the character output stream. It can provide a buffering mechanism to improve the efficiency of writing.

24.4.3.2.2 Basic use cases
// 1.创建流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("out.txt"));
// 2.写出数据
bw.write("黑马");
// 3.写出换行
bw.newLine();
// 4.关闭资源
bw.close();
24.4.3.2.3Construction method
/* 格式:
	public BufferedReader(Reader in) 
	作用:创建字符缓冲输出流对象*/
BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"))
24.4.3.2.4 Common member methods
  • public void newLine(): Write a line separator, the symbol is defined by the system property.
  • For other common methods, see Character Basic Output Stream
/* 格式:
	BufferedWriter对象.newLine()
	作用:换行*/
bw.newLine();

24.4.3.3 Member methods

illustrate:

The unique output method will judge which newline character to use according to the current operating system

24.4.4.4 Principle

The basic principle of buffered streams is that when creating a stream object, a built-in buffer array of default size (length 8192) will be created. Through buffer reading and writing, the number of system IOs can be reduced, thereby improving the efficiency of reading and writing.

​ Refer to the previous section字节缓冲流的原理

24.5 Conversion flow

Summary of notes:

  1. Overview: Read bytes and decode them into characters using the specified character set . Character set encoding conversion when reading can also be achieved
  2. InputStreamInputStreamReader _
  3. OutputStreamOutputStreamWriter _

24.5.1 Overview

24.5.1.1Definition

​ Conversion stream java.io.InputStreamReaderis a subclass of Reader and a bridge from byte stream to character stream. It reads bytes and decodes them into characters using the specified character set. Its character set can be specified by name, or it can accept the platform's default character set.

image-20230427210449500

24.5.1.1 Architecture

image-20230427210243751

24.5.2 Input stream-InputStreamReader

24.5.2.1Construction method

  • InputStreamReader(InputStream in): Create a character stream using the default character set.
  • InputStreamReader(InputStream in, String charsetName): Create a character stream of the specified character set.

Example:

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

24.5.2.2 Common member methods

  • For common methods, see Character Basic Input Stream

Example:

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();
    }
}

illustrate:

The above code is replaced by the character basic input stream in 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 Output stream-OutputStreamWriter

24.5.3.1Construction method

  • OutputStreamWriter(OutputStream in): Create a character stream using the default character set.
  • OutputStreamWriter(OutputStream in, String charsetName): Create a character stream of the specified character set.

Example:

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

24.5.3.2 Common member methods

  • For common methods, see Character Basic Output Stream

Example:

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();
    }
}

illustrate:

The above code is replaced by the character basic output stream in JDK11

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

24.5.4 Case-File encoding conversion

//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 Serialization streams

Summary of notes:

  1. Overview: An object can be represented by a byte sequence that contains information such as 对象的数据, 对象的类型and 对象中存储的属性. Persistently saves information about an object
  2. Serialization stream ObjectOutputStream : writes the original data type of Java objects to files to achieve persistent storage of objects
  3. Deserialize stream ObjectInputStream : Restore raw data previously serialized using ObjectOutputStream into objects.

24.6.1 Overview

24.6.1.1 Definition

Java provides a mechanism for object serialization . An object can be represented by a byte sequence that contains the 对象的数据, , 对象的类型and 对象中存储的属性other information. After the byte sequence is written to the file, it is equivalent to persisting the information of an object in the file .

24.6.1.1 Architecture

image-20230427214856115

24.6.2 Serialization stream-ObjectOutputStream

24.6.2.1 Overview

​Classjava.io.ObjectOutputStream , writes the original data type of Java objects to files to achieve persistent storage of objects.

24.6.2.2Construction method

  • public ObjectOutputStream(OutputStream out) : Create an ObjectOutputStream specifying the OutputStream

ObjectOutputStream(OutputStream out)

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

Notice:

  • This class must implement java.io.Serializable the interface, Serializablewhich is a marker interface. Classes that do not implement this interface will not serialize or deserialize any state and will throw NotSerializableException.

  • All properties of this class must be serializable. If there is an attribute that does not need to be serializable, the attribute must be marked as transient and modified using the transientkeyword.

  • Example:

    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 Member methods

  • public final void writeObject (Object obj): Write the specified object out
/* 格式:
	ObjectOutputStream对象.writeObject(Object obj)
    作用:将指定的对象写出*/
out.writeObject(e);

24.6.3 Deserialization stream-ObjectInputStream

24.6.2.1 Overview

ObjectInputStreamDeserialize the stream, restoring raw data previously serialized using an ObjectOutputStream into an object.

24.6.3.2 Construction method

  • public ObjectInputStream(InputStream in) : Create an ObjectInputStream specifying the InputStream.

ObjectOutputStream(OutputStream out)

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

Notice:

  1. For the JVM to deserialize an object, it must be a class that can find the class file. If the class file for the class cannot be found, an ClassNotFoundExceptionexception is thrown.
  2. When the JVM deserializes the object, the class file can be found, but if the class file is modified after the object is serialized, the deserialization operation will also fail and an InvalidClassExceptionexception will be thrown. The reason for this exception is as follows:
    • The serial version number of the class does not match the version number of the class descriptor read from the stream
    • This class contains an unknown data type
    • This class has no accessible parameterless constructor

Example:

When creating a class, add the version number

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 Member methods

  • public final Object readObject (): Read an object.

readObject ()

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

24.6.4 Case - Multiple file serialization and deserialization

Example:

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 Print stream

Summary of notes:

  1. Overview: java.io.PrintStreamClass, this class can conveniently print values ​​of various data types and is a convenient output method.
  2. Character printing stream PrintWriter : needs to output text data to files and other places, and needs richer character encoding and exception handling
  3. Byte print stream PrintStream : Need to simply output text data to the console or file

24.7.1 Overview

24.7.1.1Definition

​ Usually we print output on the console by calling printmethods and printlnmethods. Both of these methods come from java.io.PrintStreamclasses. This class can easily print values ​​of various data types and is a convenient output method.

Notice:

​ Print stream, can only be read, not written

24.7.1.2 Architecture

image-20230428101730628

24.7.2 Character printing stream PrintWriter

24.7.2.1 Overview

24.7.2.2 Construction method

image-20230428093515791

Notice:

There is a buffer at the bottom of the character stream. If you want to refresh automatically, you need to enable it.

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

24.7.2.3 Member methods

image-20230428093552198

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

24.7.3 Byte print stream PrintStream

24.7.3.1 Overview

24.7.3.2 Construction methods

image-20230428092434871

Notice:

​ There is no buffer at the bottom of the byte stream, and the automatic refresh is the same whether it is turned on or not

/* 格式:
	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 Member methods

image-20230428092734270

println()

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

detail:

  • Here, output as is in the file

    image-20230428093326196

24.7.4 Case - Changing the print stream

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);
    }
}

illustrate:

The System.out.println() method we usually use is the chain programming method of advanced print streams.

24.8 Compressing and decompressing streams (understanding)

Summary of notes:

​ Overview: Compressed files or folders

24.8.1 Overview

24.8.1.1 Meaning

Responsible for compressing files or folders

24.8.1.2 Architecture

image-20230428101544436

24.8.2 Decompressing streams

/*
*   解压缩流
*
* */
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 Compressed streams

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 Tools

Summary of notes:

  • Commons-io tool class is a set of open source toolkits related to IO operations provided by the Apache Open Source Foundation (understand)
  • Hutool tool class (emphasis):
    • HutoolIt is a feature-rich and easy-to-use Java tool library . Through the use of many practical tool classes, it is designed to help developers complete various development tasks quickly and conveniently. These encapsulated tools cover a series of operations such as strings, numbers, collections, encodings, dates, files, IO, encryption, database JDBC, JSON, HTTP clients, etc., and can meet various development needs.
    • Official Website: Getting Started and Installation (oschina.io)

image-20230812115134019

24.9.1 Commos-io

24.9.1.1 Overview

Commons-io is a set of open source toolkits related to IO operations provided by the Apache Open Source Foundation.

Function: Improve the development efficiency of I0 flow.

image-20230428102331425

24.9.1.2 Common methods of FileUtils class

image-20230428102427925

24.9.1.3 Common methods of IOUtils class

image-20230428102454674

24.9.1.4 Case-Basic Usage

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 (emphasis)

image-20230428103211173

24.9.2.1 Overview

Commons is an open source toolkit developed by Chinese people. It contains many APIs that help us improve development efficiency.

14.9.2.2 Tool class

image-20230428103826401

14.9.2.3 Case-Basic Usage

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);
    }
}

knowledge gas station

1. View the source code of this method in IDEA

If you press CTRL+B in IDEA to view the interface of this method

image-20230425111615513

Then we can select the method and view the implementation method

image-20230425111652280

2. Shortcut keys for wrapping code in IDEA

If you use the CTRL+ALT+T shortcut keys in IDEA to wrap the code

image-20230426114136309

3. Extract code shortcut keys in IDEA

Ctrl+Alt+M

image-20230429114159940

4. The extension method of exception handling in Java

image-20230427091534645

5.The difference between StringBuider and StringBuffer

image-20230429111344077

image-20230429111407230

illustrate:

The methods of StringBuider and StringBuffer in Java are the same. The difference is that StringBuffer adds a synchronization method to each method, so that when operating the method, there is only one method to operate, thereby improving code security.

Replenish:

​ If it is only a single thread, use StringBuider. If in a multi-threaded environment, thread safety needs to be considered, use StringBuffer8

6.Arrays array tool class

image-20230321135006240

In Java, Arraysa class that provides many useful static methods that can be used to manipulate and process arrays.

Here are Arrayssome common uses of classes:

  1. Arrays.toString()Method: Used to convert an array into a string.
  2. Arrays.sort()Method: Used to sort the array in ascending order.
  3. Arrays.copyOf()Method: Used to copy an array.
  4. Arrays.binarySearch()Method: Used to search for a specified element in a sorted array.
  5. Arrays.fill()Method: Used to set all elements of the array to the specified value.
  6. Arrays.equals()Method: used to compare two arrays for equality.
  7. Arrays.asList()Method: Used to convert an array into a list.

It's important to note that Arraysmost methods of a class are static methods, so you don't need to create Arraysan object to call them. In addition, Arraysthe methods in the class apply to arrays of all basic data types, as well as arrays of objects.

Guess you like

Origin blog.csdn.net/D_boj/article/details/132257791