JAVA方法引用,异常,File,IO流知识总结

文章目录

  • JAVA第六周学习笔记
  • 方法引用
    • 引用静态方法
    • 引用成员方法
    • 引用构造方法
    • 其他调用方式
      • 使用类名引用成员方法
      • 引用数组的构造方法
  • 异常
    • 作用
    • 处理方式
    • 常见成员方法
    • 抛出异常
    • finally
    • 自定义异常
  • File
    • 路径
    • 构造方法
    • **判断、获取**
    • **创建 、删除**
    • **获取并遍历**
    • 练习
  • IO流
    • 体系
    • 字节流
      • FileOutputStream
      • FileInputStream
      • try-catch处理
    • 编码
      • 标准ASCII字符集
      • GBK
      • Unicode字符集
      • 总结
      • 乱码
      • 编码与解码
    • 字符流
      • FileReader
      • FIleWriter
      • 原理分析
      • 原理分析

JAVA第六周学习笔记

方法引用

把已经有的方法拿过来用,当做函数式接口中抽象方法的方法体

::方法引用符

  1. 被引用的方法必须已经存在
  2. 被引用方法的形参和返回值需要跟抽象方法保持一致
  3. 被引用方法的功能要满足当前需求
  4. 被引用方法的功能需要满是当前的要求

引用静态方法

格式:类名::静态方法
范例:Integer::parseInt

import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Function;

public class Test {
    public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<>();
        Collections.addAll(list1, "1", "2", "3", "4");
        //使用匿名内部类来实现Function接口,将String转换为Integer
//        list1.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));

        
        // 使用流的map方法,将list1中的每个String元素转换为Integer
        // Integer::parseInt是一个方法引用,等同于上面注释掉的代码段
        list1.stream()
            .map(Integer::parseInt) // 将每个String元素转换为Integer
            .forEach(s -> System.out.println(s));
    }
}

引用成员方法

  1. 其他类的成员方法

  2. 本类的成员方法

  3. 父类的成员方法

格式:对象::成员方法

其他类:其他类对象::方法名
本类:this::方法名
父类:super::方法名

在静态方法中无法使用 this 关键字,因此只能创建类的对象引用方法。

引用构造方法

格式:类名::new
范例:Student::new

其他调用方式

使用类名引用成员方法

格式:类名::成员方法
范例:String::substring

第一个参数:表示被引用方法的调用者,决定了可以引用哪些类中的方法,在stream流当中,第一个参数一般都表示流里面的每一个数据。假设流里面的数据是字符串,那么使用这种方式进行方法引用,只能引用string这个类中的方法
第二个参数到最后一个参数:跟被引用方法的形参保持一致,如果没有第二个参数,说明被引用的方法需要是无参的成员方法

引用数组的构造方法

格式:数据类型[]::new
范例:int[]::new

技巧:

  1. 现在有没有一个方法符合我当前的需求
  2. 如果有这样的方法,这个方法是否满足引用的规则
  3. 静态: 类名::方法名
    成员方法: 三种
    构造方法: 类名::new

异常

对于异常情况,Java使用了一种称为异常处理(exception handing)的错误捕获机制。

exception

Error:代表的系统级别错误(属于严重问题)
系统一旦出现问题,sun公司会把这些错误封装成Error对象:
Error是给sun公司自己用的,不是给我们程序员用的。
因此我们开发人员不用管它,

  • Exception:叫做异常,代表程序可能出现的问题

    我们通常会用Exception以及他的子类来封装程序出现的问题

    RuntimeException及其子类,编译阶段不会出现异常提醒。

  • 编译时异常
    没有继承RuntimeExcpetion的异常,直接继承于Excpetion。编译阶段就会出现异常提醒的。(如:日期解析异常)

  • 运行时异常

    RuntimeException本身和子类。
    编译阶段没有错误提示,运行时出现的异常(如:数组索引越界异常)

Error 类: ⼀般是指与虚拟机相关的问题,如:系统崩溃、虚拟机错误、内存空间不⾜、⽅法调⽤栈溢出等。这类

错误将会导致应⽤程序中断,仅靠程序本身⽆法恢复和预防;

Exception 类:分为运⾏时异常和受检查的异常

运⾏时异常:如:空指针异常、指定的类找不到、数组越界、⽅法传递参数错误、数据类型转换错误。可以编译通过,但是⼀运⾏就停⽌了,程序不会⾃⼰处理;

受检查异常:要么⽤ try … catch… 捕获,要么⽤ throws 声明抛出,交给⽗类处理。

特征编译时异常运行时异常
检测时机在编译阶段检测到在运行时检测到
处理方式必须显式处理或声明抛出通常不需要显式处理或声明抛出
继承关系继承自 Exception继承自 RuntimeException
典型示例IOException、ParseException 等NullPointerException、ArrayIndexOutOfBoundsException 等

作用

  1. 异常是用来查询bug的关键参考信息
  2. 异常可以作为方法内部的一种特殊返回值,以便通知调用者底层的执行情况

处理方式

  1. JVM默认的处理方式
  2. 自己处理
  3. 抛出异常

格式:

try {
    可能出现异常的代码;
} catch(异常类名 变量名) {
    异常的处理代码;
}
public class test02 {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5, 6};
        try {
            System.out.println(arr[10]);
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("数组越界");
        }
        System.out.println("这里是执行的");
    }
}

目的:当代码出现异常时,可以让程序继续往下执行。

  • 如果try中没有遇到问题,怎么执行?

    catch 块将不会被执行。

  • 如果try中可能会遇到多个问题,怎么执行?

    添加多个 catch 块来捕获不同类型的异常。

    父类异常写在下面

  • 如果try中遇到的问题没有被捕获,怎么执行?

    异常将会被抛到 JVM,导致程序终止执行,并输出异常信息。

  • 如果try中遇到了问题,那么try下面的其他代码还会执行吗?

    try 块中异常发生点后面的代码将不会执行。程序会立即跳转到与异常匹配的 catch 块中执行相应的异常处理逻

常见成员方法

方法名称说明
public String getMessage()返回此 Throwable 的详细消息字符串
public String toString()返回此可抛出对象的简短描述
public void printStackTrace()将异常的错误信息输出到控制台

printStackTrace仅仅打印信息,不会结束程序

抛出异常

throws
写在方法定义处,表示声明一个异常,告诉调用者,使用本方法可能会有哪些异常

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

throw
写在方法内,结束方法,手动抛出异常对象,交给调用者,方法中下面的代码不再执行了

public void 方法() {
throw new NullPointerException();
}

编译时异常:必须要写
运行时异常:可以不写。

finally

finally关键字用来创建在 try 代码块后面执行的代码块。

无论是否发生异常,finally 代码块中的代码总会被执行。

在 finally 代码块中,可以运行清理类型等收尾善后性质的语句。

finally 代码块出现在 catch 代码块最后,语法如下:

try{
  // 程序代码
}catch(异常类型1 异常的变量名1){
  // 程序代码
}catch(异常类型2 异常的变量名2){
  // 程序代码
}finally{
  // 程序代码
}

问题一,finally是不是⼀定会被执行到?

不⼀定

  1. 在执行 finally 块之前 JVM 强制退出
  2. 执行线程被杀死
  3. 无限循环
  4. 调用了System.exit()。

问题二、try-catch-finally中,如果catch中return了,finally还会执⾏吗?

如果在 catch 块中执行了 return 语句,finally 块仍然会在返回之前执行。

对于基本数据类型,因为返回的是数值本身而不是引用,finally 块中对返回值的修改不会影响到实际的返回值。

但是对于引用类型,finally 块中对引用对象的修改会影响到返回值。这是因为引用类型的返回值是对象的地址,而不是对象本身。因此,如果在 finally 块中修改了引用对象的状态,这些修改会在返回之后仍然生效。

问题三、try-catch-finally 中那个部分可以省略?

catch 可以省略。try 只适合处理运⾏时异常,try+catch 适合处理运⾏时异常+普通异常。也就是说,如果你只⽤
try 去处理普通异常却不加以 catch 处理,编译是通不过的,因为编译器硬性规定,普通异常如果选择捕获,则必
须⽤ catch 显示声明以便进⼀步处理。⽽运⾏时异常在编译时没有如此规定,所以 catch 可以省略,你加上 catch
编译器也觉得⽆可厚⾮

自定义异常

  1. 定义异常类
  2. 写继承关系
  3. 空参构造
  4. 带参构造
  • 所有异常都必须是 Throwable 的子类。
  • 如果希望写一个检查性异常类,则需要继承 Exception 类。
  • 如果你想写一个运行时异常类,那么需要继承 RuntimeException 类。
public class CustomException extends Exception {
    // 自定义异常类的代码
}

exceptionex

意义:

自定义异常的意义在于提高程序的可读性和可维护性,使得控制台输出的错误信息更加具有意义和可理解性。通过自定义异常,为不同的错误场景定义具有描述性的异常类,使异常信息能够清晰地传达出问题的类型和原因,有助于开发人员快速定位和解决问题。

File

路径

File对象就表示一个路径,可以是文件的路径、也可以是文件夹的路径
这个路径可以是存在的,也允许是不存在的

相对路径

相对路径是相对于当前工作目录或者某个基准目录的路径描述。换句话说,相对路径描述的是一个文件或目录相对于另一个文件或目录的位置关系。

绝对路径

绝对路径是从文件系统的根目录开始的完整路径描述。无论当前工作目录在哪里,绝对路径都能够准确地描述一个文件或目录的位置。

构造方法

方法名称说明
public File(String pathname)根据文件路径创建文件对象
public File(String parent, String child)根据父路径名字符串和子路径名字符串创建文件对象
public File(File parent, String child)根据父路径对应文件对象和子路径名字符串创建文件对象
import java.io.File;

public class Test {
    public static void main(String[] args) {

        String str = "C:\\Users\\HP\\Desktop\\ggg.txt";
        File f1 = new File(str);
        System.out.println(f1);

        String parent = "C:\\Users\\HP\\Desktop\\";
        String child = "ggg.txt";
        File f2 = new File(parent, child);
        System.out.println(f2);

        File f3 = new File(parent);
        File f4 = new File(f3, child);
        System.out.println(f3);
        System.out.println(f4);

    }
}

判断、获取

方法名称说明
public boolean isDirectory()判断此路径名表示的File是否为文件夹
public boolean isFile()判断此路径名表示的File是否为文件
public boolean exists()判断此路径名表示的File是否存在
public long length()返回文件的大小(字节数量)
public String getAbsolutePath()返回文件的绝对路径
public String getPath()返回定义文件时使用的路径
public String getName()返回文件的名称,带后缀
public long lastModified()返回文件的最后修改时间(时间毫秒值)
  1. length

    • 返回的是字节
    • 无法获取文件夹大小
  2. length

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Test {
    public static void main(String[] args) {

        String str = "C:\\Users\\HP\\Desktop\\ggg.txt";
        File f1 = new File(str);
        System.out.println(f1);

        long d = f1.lastModified();
        Date date = new Date(d);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        System.out.println(sdf.format(date));

    }
}

创建 、删除

方法名称说明
public boolean createNewFile()创建一个新的空的文件
public boolean mkdir()创建单级文件夹
public boolean mkdirs()创建多级文件夹
public boolean delete()删除文件、空文件夹
  1. createNewFile创建一个新的空的文件

    • 细节1:如果当前路径表示的文件是不存在的,则创建成功,方法返回true

      ​ 如果当前路径表示的文件是存在的,则创建失败,方法返回false

    • 细节2:如果父级路径是不存在的,那么方法会有异常IOException

    • 细节3:createNewFile方法创建的一定是文件,如果路径中不包含后缀名,则创建一个没有后缀的文件

  2. mkdir(make Directory)

    • 细节1:windows当中路径是唯一的,如果当前路径已经存在,则创建失败,返回false
    • 细节2:mkdir方法只能创建单级文件夹,无法创建多级文件夹
  3. mkdirs(make Directory)创建多级文件夹

    细节:既可以创建单级的,又可以创建多级的文件夹

  4. delete

    • 如果删除的是文件:直接删除,不走回收站
    • 如果删除的是文件夹:
      • 空文件夹,直接删除,不走回收站
      • 有内容的文件夹,删除失败

获取并遍历

方法名称说明
public File[] listFiles()获取当前该路径下所有内容
  • 当调用者File表示的路径不存在时,返回null
  • 当调用者File表示的路径是文件时,返回null
  • 当调用者File表示的路径是一个空文件夹时,返回一个长度为0的数组
  • 当调用者File表示的路径是一个有内容的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回
  • 当调用者File表示的路径是一个有隐藏文件的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏文件
  • 当调用者File表示的路径是需要权限才能访问的文件夹时,返回null
方法名称说明
public static File[] listRoots()列出可用的文件系统根(获取系统中所有的盘符)
public String[] list()获取当前该路径下所有内容(仅仅能获取名字 )
public String[] list(FilenameFilter filter)利用文件名过滤器获取当前该路径下所有内容
public File[] listFiles()获取当前该路径下所有内容
public File[] listFiles(FileFilter filter)利用文件名过滤器获取当前该路径下所有内容
public File[] listFiles(FilenameFilter filter)利用文件名过滤器获取当前该路径下所有内容
import java.io.File;
import java.io.FilenameFilter;
import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
        File f2 = new File("p:\\aaa");

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

练习

找文件夹下某后缀文件,包括文件夹中的

递归

public static void findmd() {
    // 获取所有根目录
    File arr[] = File.listRoots();
    // 遍历所有根目录
    for (File f : arr) {
        // 调用findmd(File src)方法,从根目录开始递归查找.md文件
        findmd(f);
    }
}

public static void findmd(File src) {
    // 获取目录下的所有文件和子目录
    File[] files = src.listFiles();
    // 如果目录不为空
    if (files != null) {
        // 遍历目录下的所有文件和子目录
        for (File file : files) {
            // 如果是文件
            if (file.isFile()) {
                // 检查文件是否以".md"结尾,如果是则打印文件名
                if (file.getName().endsWith(".md"))
                    System.out.println(file.getName());
            } else {
                // 如果是目录,递归调用findmd(File src)方法,继续查找该子目录下的.md文件
                findmd(file);
            }
        }
    }
}

计算当前目录大小

public static long getCapticpy(File src) {
    // 获取目录下的所有文件和子目录
    File[] files = src.listFiles();
    // 初始化总字节数
    long sum = 0;
    // 如果目录不为空
    if (files != null) {
        // 遍历目录下的所有文件和子目录
        for (File f : files) {
            // 如果是文件,累加文件长度到总字节数中
            if (f.isFile()) {
                sum += f.length();
            } else {
                // 如果是目录,递归调用getCapticpy方法,将返回的字节数累加到总字节数中
                sum += getCapticpy(f);
            }
        }
    }
    // 返回总字节数
    return sum;
}

IO流

存储和读取数据的解决方案

用于读写文件中的数据(可以读写文件,或网络中的数据)

按流向分

  • 输出流:程序
  • 输入流:文件

按操作文件的类型分

  • 字节流:可以操作所有类型的文件
  • 字符流:只能操作纯文本文件

纯文本文件:用windows系统自带的记事本打开并且能读懂的文件。
例如:txt文件,md文件,xml文件,lrc文件等

体系

IOstream

字节流

FileOutputStream

操作本地文件的字节输出流,可以把程序中的数据写到本地文件中。

一、构造方法

构造方法描述
FileOutputStream(String name)使用指定的文件名创建一个 FileOutputStream 对象。如果文件不存在,会创建一个新文件。
FileOutputStream(String name, boolean append)使用指定的文件名和 append 标志创建 FileOutputStream 对象。如果 appendtrue,字节将被写入文件末尾。
FileOutputStream(File file)使用指定的 File 对象创建 FileOutputStream 对象。如果文件不存在,会创建一个新文件。
FileOutputStream(File file, boolean append)使用指定的 File 对象和 append 标志创建 FileOutputStream 对象。如果 appendtrue,字节将被写入文件末尾。
FileOutputStream(FileDescriptor fdObj)创建一个文件输出流以写入指定的文件描述符。

二、书写步骤

  1. 创建字节输出流对象
  2. 写数据
  3. 释放资源

细节

  1. 创建字节输出流对象
    细节1:参数是字符串表示的路径或者是File对象都是可以的
    细节2:如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的。
    细节3:如果文件已经存在,则会清空文件
  2. 写数据
    细节:write方法的参数是整数,但是实际上写到本地文件中的是整数在ASCII上对应的字符
  3. 释放资源
    细节:每次使用完流之后都要释放资源
import java.io.FileOutputStream;
import java.io.IOException;

public class Test {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("..\\5.20\\a.txt");
        fos.write(97);
        fos.close();
    }
}

三、write用法

方法名称说明
void write(int b)一次写一个字节数据
void write(byte[] b)一次写一个字节数组数据
void write(byte[] b, int off, int len)一次写一个字节数组的部分数据
public class Test {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("..\\5.20\\a.txt");
        String str = "abcd";
        byte[] bytes = str.getBytes();
        fos.write(bytes);
        fos.close();
    }
}

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

off:起始索引:字节数组b中的起始偏移量。表示从数组的哪个索引位置开始写入数据。(off必须是非负整数,且不能超过数组b的长度。)

len:写入字节数:这是要写入的字节数。从off位置开始,连续写入len个字节。

四、换行与续写

1.换行
写出一个换行符即可
windows:\r\n
Linux:\n
Mac:\r

在windows操作系统当中,java对回车换行进行了优化。
虽然完整的是\r\n,但是我们写其中一个\r或者\n,
java也可以实现换行,因为java在底层会补全。

2.续写

FileOutputStream(String name, boolean append)

FileOutputStream(File file, boolean append)

如果 appendtrue,字节将被写入文件末尾。

	FileOutputStream fos = new FileOutputStream("..\\5.20\\a.txt",true);

FileInputStream

操作本地文件的字节输入流,可以把本地文件中的数据读取到程序中来。

一、构造方法

构造方法参数描述
FileInputStream(File file)要读取的文件对象。
FileInputStream(String name)要读取的文件的路径名。
FileInputStream(FileDescriptor fd)文件描述符对象,表示已打开的文件。

二、书写步骤

  1. 创建字节输入流对象
  2. 读数据
  3. 释放资源

细节

    • 如果文件不存在,就直接报错。
    • 一次读一个字节,读出来的是数据在ASCII上对应的数字
    • 读到文件末尾了,read方法返回-1。
  1. 每次使用完流必须要释放资源。

三、循环读取

import java.io.FileInputStream;
import java.io.IOException;

public class Demo {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("..\\5.20\\a.txt");
        int b;
        while ((b = fis.read()) != -1) {
            System.out.print((char) b);
        }
        fis.close();
    }
}

四、read

方法名称说明
public int read()一次读取一个字节数据。
public int read(byte[] buffer)一次读取一个字节数组数据。

一般创建1024的整数倍

五、文件拷贝

public int read()

public class Demo2 {
    public static void main(String[] args) throws IOException {
        // 创建文件输入流,用于读取原始文件
        FileInputStream fis = new FileInputStream("E:\\MyMarkdown\\链表排序.md");
        // 创建文件输出流,用于写入复制后的文件
        FileOutputStream fos = new FileOutputStream("E:\\MyMarkdown\\链表排序_copy.md");
        
        int b;
        // 循环读取原始文件的字节,写入到复制后的文件中
        while((b = fis.read()) != -1){
            fos.write(b);
        }
        
        // 关闭输入流和输出流
        fos.close();
        fis.close();
    }
}

public int read(byte[] buffer)

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test02 {
    public static void main(String[] args) throws IOException {
        // 创建 FileInputStream 对象,用于读取源文件
        FileInputStream fis = new FileInputStream("..\\5.20\\a.txt");
        
        // 创建 FileOutputStream 对象,用于写入目标文件
        FileOutputStream fos = new FileOutputStream("..\\5.20\\acopy.txt");
        
        // 使用 try-with-resources 语句,确保在结束时自动关闭流
        try (fos; fis) {
            int len;
            byte[] bytes = new byte[1024];
            
            // 循环读取源文件,并将读取的数据写入目标文件
            while ((len = fis.read(bytes)) != -1) {
                fos.write(bytes, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

try-catch处理

trycatch

AutoCloseable 接口的定义:

package java.lang;

public interface AutoCloseable {
    void close() throws Exception;
}

AutoCloseable 接口只包含一个 close() 方法,该方法没有参数,并且可能会抛出 Exception 异常。类实现了 AutoCloseable 接口的意思就是它承诺可以在不再需要时释放资源,以确保资源的正常管理和释放。

使用 AutoCloseable 接口可以让资源管理更加简单和安全,在 try-with-resources 语句中使用,无需手动编写 finally 块来关闭资源。在 try-with-resources 语句中,当 try 块结束时,自动调用 close() 方法释放资源。

编码

标准ASCII字符集

美国制定,包含美国使用的英文字符等,共128个字符

每一个字符对应一个码点,码点转化为二进制,首位是0

521.1

GBK

国标,汉字编码字符集

包含两万多个汉字等字符,GBK中一个中文字符编码成两个字节形式存储

  • 汉字第一个字节的第一位必须是1,所以能代表2^15=32768

  • GBK兼容ASCII字符集

英文和ASCII一致

gbk

Unicode字符集

( 统一码,万国码)

国际组织制定,容纳世界上所有文字,符号的字符集

Unicode Transfer Format

  • UTF-32

四个字节一个字符

  • UTF-16

2-4个字节一个字符

  • UTF-8

可变长编码方案,四个长度区:1,2,3,4

英文数字,字符占一个字节,汉字字符占用三个字节

utf

总结

bianma

  • 字符编码时使用字符集和解码使用时字符集需要一致
  • 英文数字一般不会乱码

乱码

原因

  1. 读取数据时未读完整个汉字
  2. 编码和解码时的方式不统一

如何不产生乱码

  1. 不要用字节流读取文本文件
  2. 编码解码时使用同一个码表,同一个编码方式

编码与解码

方法名称说明
public byte[] getBytes()使用默认方式进行编码。
public byte[] getBytes(String charsetName)使用指定方式进行编码。
public String(byte[] bytes)使用默认方式进行解码。
public String(byte[] bytes, String charsetName)使用指定方式进行解码。
package com.feng.test03;

import java.io.UnsupportedEncodingException;

public class Test03 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String s = "ni好";
        byte[] bytes1 = s.getBytes();
        byte[] bytes2 = s.getBytes("GBK");
        System.out.println(new String(bytes1));
        System.out.println(new String(bytes2, "GBK"));
    }
}

字符流

字符流的底层其实就是字节流

字符流 = 字节流 + 字符集

特点

  • 输入流:一次读一个字节,遇到中文时,一次读多个字节
  • 输出流:底层会把数据按照指定的编码方式进行编码,变成字节再写到文件中

使用场景

对于纯文本文件进行读写操作

FileReader

一、构造方法

FileReader 构造方法

构造方法说明
public FileReader(File file)创建字符输入流关联本地文件。
public FileReader(String pathname)创建字符输入流关联本地文件。参数是文件路径的字符串表示。

如果文件不存在,就直接报错

二、书写步骤

  1. 创建字符输入流对象

​ 如果文件不存在,就直接报错

  1. 读取数据
方法签名方法功能细节
public int read()读取数据按字节读取,遇到多字节字符会一次读取多个字节并解码为整数
public int read(char[] buffer)读取数据到字符数组中按字节读取,遇到多字节字符会一次读取多个字节并解码为字符并填充到字符数组中

如果读取到文件末尾,则返回 -1。

  1. 释放资源

public int read()

默认也是一个字节一个字节的读取的,如果遇到中文就会一次读取多个,在读取之后,方法的底层还会进行解码并转成十进制。

返回值就是十进制

public class Test01 {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("a.txt");
        int i;
        while ((i = fr.read()) != -1) {
            System.out.print((char)i);
        }
    }
}

public int read(char[] buffer)

读取数据,解码,强转三步合并了,把强转之后的字符放到数组当中

相当于空参的read+ 强转类型转换

public class Test01 {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("a.txt");
        int i;
        char[] chars = new char[2];
        int len;
        while ((len = fr.read(chars)) != -1) {
            System.out.print(new String(chars, 0, len));
        }
    }
}

FIleWriter

一、构造方法

构造方法说明
public FileWriter(File file)创建字符输出流关联本地文件。
public FileWriter(String pathname)创建字符输出流关联本地文件。
public FileWriter(File file, boolean append)创建字符输出流关联本地文件,续写。
public FileWriter(String pathname, boolean append)创建字符输出流关联本地文件,续写。

二、成员方法

成员方法说明
void write(int c)写出一个字符
void write(String str)写出一个字符串
void write(String str, int off, int len)写出一个字符串的一部分
void write(char[] cbuf)写出一个字符数组
void write(char[] cbuf, int off, int len)写出字符数组的一部分

三、步骤

  1. 创建字符输出流对象

    细节1:参数是字符串表示的路径或者File对象都是可以的
    细节2:如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的
    细节3:如果文件已经存在,则会清空文件,如果不想清空可以打开续写开关

  2. 写数据

    如果write方法的参数是整数,但是实际上写到本地文件中的是整数在字符集上对应的字符

  3. 释放资源

    细节:每次使用完流之后都要释放资源

public class Test02 {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("a.txt", true);
        
        fw.write(25105);
        fw.write("???");
        char[] chars = {'a', 'b', '你'};
        fw.write(chars);
        
        fw.close();
    }
}

原理分析

一、字符输入流

  1. 创建字符输入流对象

    底层:关联文件,并创建缓冲区(长度为8192的字节数组)

  2. 读取数据

    底层:判断缓冲区中是否有数据可以读取

    • 缓冲区没有数据:就从文件中获取数据,装到缓冲区中,每次尽可能装满缓冲区,
      如果文件中也没有数据了,返回-1。
    • 缓冲区有数据:就从缓冲区中读取
      空参的read方法:一次读取一个字节,遇到中文一次读多个字节,把字节解码并转成十进制返回
      有参的read方法:把读取字节,解码,强转三步合并了,强转之后的字符放到数组中

二、字符输出流

成员方法说明
public void flush()将缓冲区中的数据,刷新到本地文件中
public void close()释放资源/关流

flush刷新:刷新之后,还可以继续往文件中写出数据

close关流:断开通道,无法再往文件中写出数据
数在字符集上对应的字符

  1. 释放资源

    细节:每次使用完流之后都要释放资源

public class Test02 {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("a.txt", true);
        
        fw.write(25105);
        fw.write("???");
        char[] chars = {'a', 'b', '你'};
        fw.write(chars);
        
        fw.close();
    }
}

原理分析

一、字符输入流

  1. 创建字符输入流对象

    底层:关联文件,并创建缓冲区(长度为8192的字节数组)

  2. 读取数据

    底层:判断缓冲区中是否有数据可以读取

    • 缓冲区没有数据:就从文件中获取数据,装到缓冲区中,每次尽可能装满缓冲区,
      如果文件中也没有数据了,返回-1。
    • 缓冲区有数据:就从缓冲区中读取
      空参的read方法:一次读取一个字节,遇到中文一次读多个字节,把字节解码并转成十进制返回
      有参的read方法:把读取字节,解码,强转三步合并了,强转之后的字符放到数组中

二、字符输出流

成员方法说明
public void flush()将缓冲区中的数据,刷新到本地文件中
public void close()释放资源/关流

flush刷新:刷新之后,还可以继续往文件中写出数据

close关流:断开通道,无法再往文件中写出数据


如有错误烦请指正

感谢您的阅读

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/647454.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

yolov8报警图片写入minio服务器 Rabbitmq发送地址

OSError [WinError 1455]页面文件太小&#xff0c;无法完成操作”解决方案“_深度学习_yangshejun-GitCode 开源社区 (csdn.net) python对RabbitMQ的简单使用_python rabbitmq-CSDN博客 【Windows安装RabbitMQ详细教程】_rabbitmq windows-CSDN博客 Windows 10安装Minio 文件…

学 Go 具体能干什么?

学习 Go (Golang) 后&#xff0c;你可以从事许多不同的工作和项目&#xff0c;Go 语言以其高性能、并发处理和简洁的语法而闻名&#xff0c;特别适合以下几个领域&#xff1a; 1. 后端开发 Go 在后端开发中非常流行&#xff0c;特别适合构建高性能的 Web 服务和 API。 Web 框…

脑机接口习题

9-12章习题 填空题 EEG电极分为 主动电极 和 被动电极 &#xff0c;其中 被动电极 直接与放大器连接&#xff0c; 主动电极 包含一个1~10倍的前置放大。除抗混淆滤波器&#xff0c;放大系统也包含由电阻器、电容器构成的模拟滤波器&#xff0c;把信号频率内容限制在一个特定的…

【QT+VS】如何在现有VS项目中添加Qt界面?【全网最详细】

0. 前置步骤 参考如下链接文章中的 前3个步骤(1:下载Qt;2:安装Qt;3:安装Qt插件),完成环境的配置和安装。 深耕AI:如何联合Qt,VS,C++,来开发一个电脑版软件(简单有趣,详细) 本文的基础项目链接为: c++工程+图像分割预测+mmdet+实例分割+最新工程+简洁易懂+新手…

斯坦福2024人工智能指数报告 1

《人工智能指数报告》由斯坦福大学、AI指数指导委员会及业内众多大佬Raymond Perrault、Erik Brynjolfsson 、James Manyika、Jack Clark等人员和组织合著&#xff0c;旨在追踪、整理、提炼并可视化与人工智能&#xff08;AI&#xff09;相关各类数据&#xff0c;该报告已被大多…

Redis学习篇2:Redis在Spring中的应用

本文继上文开始讲述了Redis在IDEA中如何应用以及集成进入spring开发环境&#xff0c;以及如何使用Redis客户端。上一个文章&#xff1a;Redis学习篇1&#xff1a;初识Redishttps://blog.csdn.net/jialuosi/article/details/139057088 一、Redis在java中的客户端 二、SpringDat…

前缀和,差分算法理解

前缀和是什么&#xff1a; 前缀和指一个数组的某下标之前的所有数组元素的和&#xff08;包含其自身&#xff09;。前缀和分为一维前缀和&#xff0c;以及二维前缀和。前缀和是一种重要的预处理&#xff0c;能够降低算法的时间复杂度 说个人话就是比如有一个数组&#xff1a; …

基于ssm的蛋糕商城系统java项目jsp项目javaweb

文章目录 蛋糕商城系统一、项目演示二、项目介绍三、系统部分功能截图四、部分代码展示五、底部获取项目源码&#xff08;9.9&#xffe5;带走&#xff09; 蛋糕商城系统 一、项目演示 蛋糕商城管理系统 二、项目介绍 系统角色 : 管理员、用户 一&#xff0c;管理员 管理员有…

Android硬件渲染流程

Android硬件渲染流程 一.渲染流程1.VSync信号的监听2.VSync信号触发绘制 二.渲染原理1.画布的获取1.1 画布的创建1.2 渲染指令列表的创建 2.绘制与渲染指令2.1 矩形的绘制2.2 硬件渲染指令2.3 节点的绘制 3.绘制的提交3.1 绘制结果的保存3.2 绘制结果的获取 4.层级的构建4.1 绘…

Docker 安装kingbase V8r6

下载 官网下载&#xff0c;注意&#xff1a;这里下载 Docker 版本v8r6 安装 # 导入镜像 docker load -i kingbase.tar# 重命名 docker tag [image-name]:[tag] [new-image-name]:[new-tag]# 删除 docker rmi [image-name]:[tag]# 创建容器 docker run -tid \ --privileged \…

2024-6-遥远的救世主

2024-6-遥远的救世主 2024-4-18 豆豆 fatux&#xff1a; 2021.5.26 看完电视剧《天道》之后购买本书&#xff0c;断断续续一直没有读完。 非常好奇&#xff0c;一个什么样的作者能写出如此奇书。老丁&#xff0c;一个智者&#xff0c;智者是多么孤独&#xff0c;因为找不到同…

Javascript特效之鼠标悬停特效【css】

先看一看效果&#xff0c;是不是很炫酷啊&#xff1f;&#xff1f; HTML代码&#xff1a; <!DOCTYPE html> <html><head><meta charset""UTF-8"" /><title>CSS特效&#xff1a;鼠标悬停效果</title><link rel&q…

Linux下Vision Mamba环境配置+多CUDA版本切换

上篇文章大致讲了下Vision Mamba的相关知识&#xff0c;网上关于Vision Mamba的配置博客太多&#xff0c;笔者主要用来整合下。 笔者在Win10和Linux下分别尝试配置相关环境。 Win10下配置 失败 \textcolor{red}{失败} 失败&#xff0c;最后出现的问题如下&#xff1a; https://…

深入了解数据库设计中的规范化与反规范化

目录 零、前言 一、一些基本术语 二、关系模式 2.1. 什么是关系模式 2.2. 示例 三、数据依赖 3.1. 函数依赖 3.1.1. 完全函数依赖 3.1.2. 部分函数依赖 3.1.3. 传递函数依赖 3.2. 多值依赖 3.3. 连接依赖 四、规范化 4.1. 第一范式&#xff08;1NF&#xff09; …

C++/ cuda kernel中的模版元编程识别 kernel 模版的数据类型

1&#xff0c;模版元编程 模板元编程是一种利用 C 模板系统在编译时进行计算和生成代码的技术。其原理基于模板特化、递归、模板参数推导等特性&#xff0c;通过模板实例化和展开&#xff0c;在编译时生成代码&#xff0c;以实现在编译期间进行复杂计算和代码生成的目的。 2&am…

Git--本地仓库

文章目录 工作区和暂存区工作区&#xff08;Working Directory&#xff09;版本库&#xff08;Repository&#xff09; 初始化git仓库添加文件到版本库步骤 查看修改内容查看工作区和暂存区状态已add文件已修改/新增 的未add文件git跟踪修改原理 查看提交历史版本回退撤销修改撤…

【组合数学】常考试题答案

一、单项选择题&#xff08;每小题3分&#xff0c;共15分&#xff09; 1. 用3个“1”和4个“0”能组成&#xff08; &#xff09;个不同的二进制数字。 A. 35 B. 36, C. 37, D. 38 2. 整除300的正整数的个数为&#xff08;  &#xff09;。 A. 14…

面试中算法(A星寻路算法)

一、问题需求&#xff1a; 迷宫寻路游戏中&#xff0c;有一些小怪物要攻击主角&#xff0c;现在希望你给这些小怪物加上聪 明的AI (Artificial Intelligence&#xff0c;人工智能&#xff09;&#xff0c;让它们可以自动绕过迷宫中的障碍物&#xff0c;寻找到主角的所在。 A星…

DNS服务的部署与配置(2)

1、dns的安装及开启 dnf install bind.x86_64 -y #安装 #Berkeley Internet Name Domain (BIND) systemctl enable --now named #启用dns服务&#xff0c;服务名称叫named firewall-cmd --permanent --add-servicedns #火墙设置 firewall-cmd --reload …

学 Java 具体能干什么?

学习 Java 后&#xff0c;你可以从事许多不同的工作和项目&#xff0c;涵盖了广泛的应用领域。以下是一些具体的应用场景和工作方向&#xff1a; 1. 企业级应用开发 Java 是企业级应用开发的首选语言之一&#xff0c;特别适合开发大规模、分布式、多层次的企业应用程序。 Jav…