异常

异常概述:

Exception:叫做异常,代表程序可能出现的问题。
运行时异常:RuntimeException以及子类,编译阶段不会出现运行时异常提醒。
编译时异常:编译阶段就会出现的异常提醒。

编译时异常和运行时异常区别:

编译时异常:除了RuntimeException和他的子类,其它都是编译时异常。编译阶段需要进行处理,作用在于提醒程序员。
运行时异常:一般是由于参数传递错误带来的问题。

异常的作用:

可以用来查询bug的关键参数信息
异常可以作为方法内部的一种特殊的返回值,告诉调用这底层的执行情况。

JVM默认处理异常的方式:

1.把异常的名称,异常的原因以及异常出现的位置等信息输出在控制台中。
2.程序停止执行,异常下面的代码不会执行。

try…catch

//如果出现错误了就会创建出这个异常的对象,然后再拿到catch中去对比看和那个异常是否是同一种类,如果相同,就去执行catch中的语句。
try{...}catch(异常类型 变量名){...}

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

执行完try中的语句,就直接执行下catch以外的语句。

try可能出现多个问题怎么执行?

写多个catch与之对应,如果在catch中没有找到对应的异常就会直接报错。
如果有多个问题,如果第一个问题被捕获了就直接执行catch中的代码,如果第一个问题没有被捕获就会直接报错。
注意:如果有多个catch,如果catch中的异常对象有父子关系,就需要把父类凡在最后面。

int[] arr = {1,2,3,4};
        try {
            System.out.println(10/0);
            System.out.println(arr[10]);
        }catch(ArrayIndexOutOfBoundsException e){
            System.out.println(e.getMessage());
        }catch (ArithmeticException e){
            System.out.println(e.getMessage());
        }

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

会直接报错。

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

不会执行,要么执行catch中的代码,如果没有捕获到就直接报错。

异常中的常用方法

在这里插入图片描述
toString返回简短的错误信息
getMessage返回详细的错误信息
printStackTrace把错误信息通过红色字体打印在控制台中,但是不会终止程序。

抛出:throw throws

throws告诉调用者可能会出现的异常
throw返回异常给调用者。

throw一般用在方法体中,catch一般在主函数中。

自定义异常

细节:类需要见名知意。最好是xxxException。
如果是编译异常就继承Exception.
如果是运行时异常就继承RuntimeException.

File

1.File表示什么?
File对象表示路径,可以是文件,也可以是文件夹。
这个路径可以存在,也可以不存在
2.绝对路径和相对路径是什么意思?
绝对路径是带盘符的。
相对路径是不带盘符的,默认在当前项目下找。

File的构造方法

在这里插入图片描述

String str = "D:\\Java\\JavaSE\\day17-code\\src\\My_File\\demo1.java";
        File f1 = new File(str);
        System.out.println(f1);
        String parent = "D:\\Java\\JavaSE\\day17-code\\src\\My_File";
        String child = "demo1.java";

        File f2 = new File(parent,child);

        System.out.println(f2);

        File f3 = new File(parent);
        File f4 = new File(f3,child);

        System.out.println(f4);

File的成员方法

在这里插入图片描述

//        File f1 = new File("D:\\java-learn\\java-project\\day17-code\\src\\new_file\\aaa.txt");
        // 创建一个文件
//        boolean b = f1.createNewFile();
//        System.out.println(b);

//        File f2 = new File("D:\\java-learn\\java-project\\day17-code\\src\\new_file\\bbb");
//        boolean b = f2.mkdir();
//        System.out.println(b);
//
//        File f3 = new File("D:\\java-learn\\java-project\\day17-code\\src\\new_file\\bbb\\ccc\\ddd");
//        boolean b2 = f3.mkdirs();
//        System.out.println(b2);

//        File f4 = new File("D:\\java-learn\\java-project\\day17-code\\src\\new_file\\bbb\\ccc\\a.txt");
//        System.out.println(f4.mkdir());

        // 如果文件存在,就直接删除。如果不存在就返回false
        // 如果文件夹是空的就删除成功,如果不是空的就返回false
         File f5 = new File("D:\\java-learn\\java-project\\day17-code\\src\\new_file");
//        System.out.println();
        // 获取当前路径下的内容
         File[] f = f5.listFiles();
         for(File i : f){
             System.out.println(i);
         }

细节:
如果调用者File是文件,就返回null。
如果调用者File路径不存在,返回null。
如果调用者个File是一个空的文件夹,返回长度为0的数组。
如果调用者File表示的路径是一个又内容的文件夹时,将里面所有的文件和文件夹路径都放在file数组中返回。
当调用者file表示的路径是有隐藏文件是,也是全部都返回在file数组中。
在这里插入图片描述

File[] lists = f2.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                File src = new File(dir,name);
                return src.isFile() && name.endsWith(".txt");
            }
        });

IO流

io的概述

1.什么是io流?
存储和读取数据的解决方案。
2.io流的作用?
用于读取数据(本地文件,网络)
3.io流按照操作文件的类型可以分为哪两种流?
字节流:可以操作所有类型的文件。
字符流:只能操作纯文本。
3.什么是纯文本文件?
用window系统自带的记事本能打开并且没有乱码的文件,比如txt文件,md文件,xml文件,lrc文件等等.

字符输出流写出数据的细节

FileOutputStream细节:
1.参数可以是字符串形式的路径 ,也可以是File对象
2.如果文件不存在就会创建一个新的文件,但是要确保父级路劲存在。
3.如果文件存在,会清空文件。
5.write方法的参数是整数,对应ascll上的字符
4.每次使用完流之后要释放资源

写出数据的三种方式

在这里插入图片描述

write(byte[],int off,int len);
写入多个数据,从off下标开始,写len个数据

换行与续写

 // 追加只需要添加一个参数true
        FileOutputStream fos = new FileOutputStream(".//day17-code//a.txt",true);
  			// \n 或者 \r 或者 \r\n 都是换行的意思
        String s = "kankelaoyezuishuai\n";
        byte[] b = s.getBytes();
        fos.write(b);

        String s1 = "666\n";
        fos.write(s1.getBytes());

        fos.close();

字节输入流的基本用法

//如果文件不存在,就直接报错
//每次读读取一个字符,读不到了返回-1;
int b = fis.read();

字节流文件的拷贝

一个字节一个字节的拷贝:

        FileOutputStream fos = new FileOutputStream(".\\day17-code\\b.txt");
        FileInputStream fis = new FileInputStream(".\\day17-code\\a.txt");

        byte b;

        while((b = (byte)fis.read())!=-1){
            fos.write(b);
        }

        //最先关闭输出流,再关闭输入流
        fis.close();
        fos.close();

一次拷贝多个数据:

FileOutputStream fos = new FileOutputStream(".\\day17-code\\b.txt");
        FileInputStream fis = new FileInputStream(".\\day17-code\\a.txt");

        byte[] b = new byte[100];

        int s = fis.read(b);
        System.out.println(s);
        fos.write(b,0,s);

        fis.close();
        fos.close();
//如果想计算这个程序的运行时长
long start = System.currentTimeMillis();
.....
long end = System.currentTimeMillis();

System.out.printf(end-start);

字符集

ASCLL,GBK:
1.在计算机中,任意数据都是以二进制形式来存储的
2.计算机中最小的存储单元是一个字节
3.ascll字符集中,一个英文只占一个字节
4.简体中文版window中,默认是使用GBK字符集
5.GBK字符集完全兼容ascll字符集
一个英文占一个字节,二进制第一位是0,
一个中文占两个字节,二进制第一位是1。
Unicode:
utf-8是Unicode的一种编码格式
1个英文占一个字节,二进制第一位是0,转成十进制是整数
1个汉字占三个字节,二进制第一位是1,转成十进制是负数。
如何不产生乱码?
不要使用字节流读取文本文件
编码解码时需要使用同一个码表,同一种编码方式。
为什么使用字节流拷贝文本文件时不会出现乱码?
一个一个字节拷贝时,数据源的数据并没有丢失,只要编码规则和数据源的解码方式是一样的就行

字符流读取数据

   FileReader fr = new FileReader(".\\day17-code\\b.txt");


//         while((ch = fr.read())!= -1){
//             System.out.print((char)ch);
//         }
        char[] chs = new char[2];
        int s;
//        System.out.println(Arrays.toString(chs));
        while((s = fr.read(chs)) != -1){
            System.out.print(new String(chs,0,s));
        }
        fr.close();

字符流输出流输出数据

在这里插入图片描述
在这里插入图片描述


```java
FileWriter fw =new FileWriter(".\\day17-code\\b.txt");
          fw.write("侯圆圆最帅!\r\n");
          fw.write("小王最帅\nhhhh\n",0,5);
          String s = "houyuanyuan侯圆圆\n";
          char[] arr = new char[s.length()];
          s.getChars(0,s.length(),arr,0);
          fw.write(arr);
          fw.write(arr,0,5);
          fw.close();

字符流原理分析

创建字符流对象:
底层:关联文件,创建缓冲区
读取数据:
判断缓冲区中是否有字符:
如果没有就到文件中读取数据,尽可能的填满缓冲区。如果文件中没有数据了,就直接返回-1
如果有,就直接在缓冲区中读取数据
空参read方法:如果是英文就读取一个字节,中文就读取三个字节,把字节解码并转化为十进制返回。
有参的read方法:把读取字节,解码,强转三步合并了,强转之后欧的字符放在数组中。

字节缓冲流

在这里插入图片描述

在底层会创建一个8192的缓冲流,在在程序最后不需要关闭基本流,只需要关闭缓冲流,因为在底层会关闭基本流。

BufferedInputStream(InputStream is);
BufferedOutputStream(OutputStream os);

在这里插入图片描述
缓冲流有几种?
字节缓冲输入流:BufferedInputStream()
字节缓冲输出流:BufferedOutputStream()
字符缓冲输入流:BufferedReader
字符缓冲输出流:BufferedWriter
缓冲流为什么能提高性能?
缓冲流自带长度为8192的缓冲区
可以显著提高字节输入流的读写能力
对字符流的提升不明显,但是有两个特殊方法
字符缓冲输入流:BufferedReader: readLine()
字符缓冲输出流:BufferedWrite: newLine();

转换流

是字符流和字节流之间的桥梁
作用1:指定字符集读写。
作用2:字节流想要使用字符流中的方法。

//jdk11之后引入的新方法 :指定读取的字符集
FileReader fis = new FileReader(new File(".\\day17-code\\gbkfile.txt"), Charset.forName("GBK"));
        int ch;
        while((ch = fis.read()) != -1){
            System.out.print((char)ch);
        }
        fis.close();

练习:把本地GBK文件,转化为UTF-8文件

FileReader fis = new FileReader(new File(".\\day17-code\\gbkfile.txt"), Charset.forName("GBK"));
        FileWriter fos = new FileWriter(new File(".\\day17-code\\a.txt"),Charset.forName("UTF-8"));

        int ch;

        while((ch = fis.read()) != -1){
            fos.write(ch);
        }
        
        fos.close();
        fis.close();

转换流的名字是:
InputStreamReader
OutputStreamWrite
转换流的作用是什么?
指定字符集读取数据
字节流想要使用字符流中的方法。

序列化流

在这里插入图片描述

//用序列化流把对象读取到文件中
Student s = new Student("张三", 18);

        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\java-learn\\java-project\\day17-code\\src\\cope.txt"));
        oos.writeObject(s);

        oos.close();
//创建反序列化流对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(("D:\\java-learn\\java-project\\day17-code\\src\\cope.txt")));
        //读取对象
        Student s = (Student) ois.readObject();
        System.out.println(s);
        ois.close();

1.使用序列化流将对象写在文件中时,需要让javabean类实现Serializable接口
2.序列化之后修改了javabean类,再次反序列化,会不会有问题?
有有异常,需要再javabean类中添加serialVersionUID(序列号,版本号)
3.如果一个对象中的莫个成员变量不想被序列化,可以用transient(瞬态关键字)关键字修饰

当我们不知道文件中有多少个对象的时候,我们可以把对象都添加到集合中,然后读取的时候也直接读取一个集合就行。
还有一种方法就是,直接循环读,因为全部读完之后在读就会抛出异常,这个时候我们用catch捕获就行。

打印流

字节打印流

构造方法:
在这里插入图片描述
常用成员方法:
在这里插入图片描述

字符打印流

构造方法:
在这里插入图片描述
常用成员方法:
和字节打印流一样的

字节打印流和字符打印流的区别:
字符输出流底层有缓冲区,所以需要再autoflush参数为true

压缩流/解压缩流

文件的解压缩:

package My_printStream;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class demo3 {
    public static void main(String[] args) throws IOException {


        File src = new File(".\\day17-code\\src\\new_file.zip");
        File dest = new File(".\\day17-code\\dest");
        unzip(src,dest);

    }

    public static void unzip(File src, File dest) throws IOException {
        ZipInputStream zis = new ZipInputStream(new FileInputStream(src));

        ZipEntry entry;
        while((entry = zis.getNextEntry()) != null) {
            System.out.println(entry.toString());
            if(entry.isDirectory()){

                File dir = new File(dest,entry.toString());
                dir.mkdirs();

            }else{
               File file = new File(dest,entry.toString());
//               FileInputStream fis = new FileInputStream(file);
               FileOutputStream fos = new FileOutputStream(file);

               int b;
               while((b = zis.read()) != -1){
                   fos.write(b);
               }

               fos.close();
               zis.closeEntry();
            }

        }
        zis.close();
    }

}

Commons-io

一个工具包
在这里插入图片描述

hutool

在这里插入图片描述

制造假数据

在这里插入图片描述

properties

properties是双列集合,拥有map集合所有的特点
还有一些特有的方法,可以把集合中的数据,按照键值对的形式写在配置文件中,也能从配置文件中读取数据到集合中来。

把数据存储到配置文件中去

        Properties pro = new Properties();
        // 添加数据
        pro.put("username","zhangsan");
        pro.put("password","123456");
        pro.put("url","jdbc:mysql://localhost:3306/test");
        pro.put("driver","com.mysql.jdbc.Driver");
//        System.out.println( pro);
//        Set<Object> set = pro.keySet();
//        for(Object obj : set){
//            Object value = pro.get(obj);
//            System.out.println(obj + ":" + value);
//        }

//        for(Map.Entry<Object,Object> entry : pro.entrySet()){
//            System.out.println(entry.getKey() +"="+entry.getValue());
//        }

        //把数据储存在文件中去(文件必须以Properties为后缀)
        FileOutputStream fos = new FileOutputStream("D:\\java-learn\\java-project\\day17-code\\src\\myProperties\\save.Properties");
        pro.store(fos,"test");
        fos.close();

读取配置文件

        Properties pro = new Properties();
 
        FileInputStream fis = new FileInputStream("D:\\java-learn\\java-project\\day17-code\\src\\myProperties\\save.Properties");

        pro.load(fis);

        fis.close();

        System.out.println( pro);
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐