JAVA笔记04

advance阶段

伤情最是晚凉天,憔悴斯人不堪怜。
邀酒摧肠三杯醉,寻香惊梦五更寒。
钗头凤斜卿有泪,荼蘼花了我无缘。
小楼寂寞心宇月,也难如钩也难圆。

啪!今天整理。

异常处理

导致程序的正常流程被中断的事件,叫做异常

文件不存在异常

FileNotFoundException
文件调用的一般流程

File file = new File("C:\\Users\\lhhsd\\Desktop\\基础教学\\text.c");
new FileInputStream(file);

解析异常

ParseException
由于解析函数传入的参数格式不正确

可查异常CheckedException

可查异常为必须处理的异常,比如说想FileNotFoundException,如果不处理,编译器就不会让你通过,也就是说,我必须把可能出现异常的代码段放到try catch中去,或者在方法外面定义上throws函数

运行时异常RuntimeException

也就是说不是必须进行try catch 的异常,即便不进行try catch也不会有编译错误,主要是因为一些异常太过普遍,如果都需要进行捕捉,代码的可读性就会变得很糟糕,常见的异常,比如说想 数组越界,空指针问题

异常处理的方式

  • try catch
try{
	coding
}catch(exceprion e){
	e.printStackTrace();
}
  • 多异常处理方法方法
try{
	coding
}catch(exception1 e){
	coding
}
catch(exception2 e){
	coding
}

或者

        try {
            System.out.println("试图打开 d:/LOL.exe");
            new FileInputStream(f);
            System.out.println("成功打开");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date d = sdf.parse("2016-06-03");
        } catch (FileNotFoundException | ParseException e) {
            if (e instanceof FileNotFoundException)
                System.out.println("d:/LOL.exe不存在");
            if (e instanceof ParseException)
                System.out.println("日期格式解析错误");
 
            e.printStackTrace();
        }

finally模块

无论是否出现异常finally模块里面的内容最终都会执行,如果说finally块中存在return语句的话则会返回finally中的值

throws&&throw

throws表示,本地不处理的异常,我要丢出去位置为方法声明的地方.在方法外面

而throw表示,我如果执行了某一句话,就应该是发生了异常,这个时候我要抛出异常,被外界捕获到,throws只是说明可能会出现异常,而throw表示一定会抛出某个异常对象,在方法内部。

error

值得时系统级别的异常,通常是内存用光了,一般JAVA程序启动的时候,最大可以使用16M的内存,常见的错误时OutMemoryError

在这里插入图片描述

不能被捕捉的错误和运行时异常

运行时异常 RuntimeException ,因为这些往往是运行时异常往往是因为人为的代码bug造成的
仅仅靠try-catch是不够的,只能在代码里找出bug修复,不管的话,运行时还是会出错,建议暂停运行程序,修复
面试题常问题:: 运行时异常与非运行时异常的区别:
运行时异常是不可查异常,不需要进行显式的捕捉
非运行时异常是可查异常,必须进行显式的捕捉,或者抛出

错误error时系统级别的异常,无法通过程序代码预先trycatch住

如果出现了RuntimeException异常,那一定是程序的问题。。所以出现这种异常的时候,不应该想着捕获,而是修改你的程序。

Throwable类

Throwable是类,Exception和Error都继承了该类,所以在捕捉的时候也都可以使用Throwable进行捕捉

public class TestException {
 
    public static void main(String[] args) {
 
        File f = new File("d:/LOL.exe");
 
        try {
            new FileInputStream(f);
            //使用Throwable进行异常捕捉
        } catch (Throwable t) {
            // TODO Auto-generated catch block
            t.printStackTrace();
        }
 
    }
}

自定义异常

一般步骤:
继承Exception类,默认提供两个构造方法,有参和无参

class EnemyHeroIsDeadException extends Exception{
     
    public EnemyHeroIsDeadException(){
         
    }
    public EnemyHeroIsDeadException(String msg){
        super(msg);
    }
}

之后可以抛出该异常

I/O文件

I/O文件对象

无论是文件还是文件夹都使用File代表

创建方法

使用绝对路径,或者相对路径进行创建,如果是使用相对路径进行创建更多的是使用

 File file = new File("C:\\Users\\lhhsd\\Desktop\\基础教学\\t.c");
        System.out.println(file.getAbsoluteFile());
        //获取当前文件的绝对路径
        File file1 = new File(file,"Lol.exe");
        
        System.out.println(file.getAbsoluteFile());
        System.out.println("当前文件是:"+file);//直接输出当前的文件名称
        System.out.println(file.exists());//判断当前文件是否存在
        System.out.println(file.isDirectory());//判断当前文件是否为目录
        System.out.println(file.isFile());//判断当前文件是否为文件
        System.out.println(file.length());//判断当前文件的长度
        long time = file.lastModified();//判断给当前文件最后一次修改的时间
        Date date = new Date(time);
        System.out.println(date);
        file.setLastModified(0);//设置最后一次修改事件,参数可以为long数字
        File file2 =new File("C:\\Users\\lhhsd\\Desktop\\t.c");
        file.renameTo(file2);//进行文件的重命名或者位置移动
        file.list();//如果当前文件是一个目录,则返回当前目录下的所有的文件
        File[]files = file.listFiles();//如果当前文件时一个目录,则返回文件目录下的所有的文件信息,通过文件数组的方式

        System.out.println(file.getParent());//以字符串形式返回获取当前文件的上级绝对路径或相对路径
        file.getParentFile();//以文件形式返回
        file.mkdir();//根据file名称创建文件,父目录必须存在
        file.mkdirs();//创建文件夹,如果父文件夹skin不存在,就会创建父文件夹
        file.createNewFile();// 创建一个空文件,如果父文件夹skin不存在,就会抛出异常
        file.getParentFile().mkdirs(); // 所以创建一个空文件之前,通常都会创建父目录
        file.listRoots();// 列出所有的盘符c: d: e: 等等
        file.delete();// 刪除文件
        file.deleteOnExit();// JVM结束的时候,刪除文件,常用于临时文件的删除

当不同的介质之间有数据交互的时候,JAVA就使用流来实现。
数据源可以是文件,还可以是数据库,网络甚至是其他的程序

比如读取文件的数据到程序中,站在程序的角度来看,就叫做输入流
输入流: InputStream
read返回值为-1代表文件结束
输出流:OutputStream

File f = new File("d:/lol.txt");
// 创建基于文件的输入流
FileInputStream fis = new FileInputStream(f);
// 通过这个输入流,就可以把数据从硬盘,读取到Java的虚拟机中来,也就是读取到内存中

所有的数据存放在计算机中都是以数字的形式存放的。 所以字母就需要转换为数字才能够存放。

输入字节流

InputStream是字节输入流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。
FileInputStream 是InputStream子类,以FileInputStream 为例进行文件读取。
FileInputStream的方法 read()

FIle file = new File(url);
FileInputStream f = new FileInputStream(file);
byte[]all = byte [file.length()];
f.read(all);//把f中的数据转换为输入流,传入到byte数组中去

输出字节流

OutputStream是字节输出流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。
FileOutputStream 是OutputStream子类,以FileOutputStream 为例向文件写出数据
FileInputStream的方法 write()

FIle in_file = new File(url);
File out_file = new File(url)
FileInputStream f = new FileInputStream(in_file);
FileOutputStream out = new FileOutputStream (out_file);
byte[]all = byte [file.length()];
f.read(all);//把f中的数据转换为输入流,传入到byte数组中去
out.write(all)//把all数组中的数据转换为输出流,传入到out对应的文件中去

输入字符流

Reader字符输入流
FileReader 是Reader子类,以FileReader 为例进行文件读取

public static void main(String[] args) {
        File in_file = new File("d:/text.txt");
        File out_file = new File("d:/res.txt");
        try(FileReader fileReader = new FileReader(in_file);
            FileWriter fileWriter = new FileWriter(out_file))  {
            char[]files =new char[(int)in_file.length()];
            fileReader.read(files);
            fileWriter.write(files);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

输出字符流

Writer字符输出流

关闭流的方法

  • 方法一
    在try结构体中直接关闭,缺点,触发异常之后直接抛出,不会执行close函数
  • 方法二
    这是标准的关闭流的方式
  1. 首先把流的引用声明在try的外面,如果声明在try里面,其作用域无法抵达finally.
  2. 在finally关闭之前,要先判断该引用是否为空
  3. 关闭的时候,需要再一次进行try catch处理
 finally {
            // 在finally 里关闭流
            if (null != fis)
                try {
 
                    fis.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        }
  • 方法三
    使用try()方法,jdk开始支持,所有流实现接口叫做AutoCloseable
try(FileInputStream fis = new FileInputStream(f)){

}

在try中定义的方法会自动进行close,并回收相关资源,要求必须在try中进行实例化

编码问题

计算机存放数据只能存放数字,所有的字符都会被转换为不同的数字,常见的编码格式:
ISO支支持英文字符
GBK支持中英文
UNICODE支持万国文
UTF-8瘦身字节码

Java采用的是Unicode。
ANSI 这个不是ASCII的意思,而是采用本地编码的意思。如果你是中文的操作系统,就会使GBK,如果是英文的就会是ISO-8859-1

用FileInputStream 字节流正确读取中文
FileInputStream 处理方法为:
对结果使用 String str = new String(all,“GBK”);
用FileReader 字符流正确读取中文
FileReader得到的是字符,所以一定是已经把字节根据某种编码识别成了字符了。
FileReader是不能手动设置编码方式的,为了使用其他的编码方式,只能使用InputStreamReader来代替,像这样:
new InputStreamReader(new FileInputStream(f),Charset.forName("UTF-8"));
为什么中字前面有一个?
如果是使用记事本另存为UTF-8的格式,那么在第一个字节有一个标示符,叫做BOM用来标志这个文件是用UTF-8来编码的。

缓存流

以介质是硬盘为例,字节流和字符流的弊端:
在每一次读写的时候,都会访问硬盘。 如果读写的频率比较高的时候,其性能表现不佳。
为了解决以上弊端,采用缓存流

缓存流读入

缓存流在读取的时候,会一次性读较多的数据到缓存中,以后每一次的读取,都是在缓存中访问,直到缓存中的数据读取完毕,再到硬盘中读取。
BufferedReader
缓存字符输入流 BufferedReader 可以一次读取一行数据。
缓存流必须建立在一个存在的流的基础上一般为FileReader

缓存流写入

缓存流在写入数据的时候,会先把数据写入到缓存区,直到缓存区达到一定的量,才把这些数据,一起写入到硬盘中去。按照这种操作模式,就不会像字节流,字符流那样每写一个字节都访问硬盘,从而减少了IO操作。
PrintWriter和BufferWriter的区别

   File in_file = new File("d:/text.txt");
        File out_file = new File("d:/out.txt");
        try(    FileReader fileReader = new FileReader(in_file);
                FileWriter fileWriter = new FileWriter(out_file);
                BufferedReader bufferedReader = new BufferedReader(fileReader);
                PrintWriter printWriter = new PrintWriter(fileWriter);
                ) {
           while (true){
               String line = bufferedReader.readLine();
               if (line==null)break;
               System.out.println(line);
               printWriter.println(line);
           }

flush函数

有时候如果缓存区没有满我们也要直接把内容写入,对PrintWriter对象使用flush方法

数据流

DataInputStream 数据输入流
DataOutputStream 数据输出流
使用数据流的writeUTF()和readUTF() 可以进行数据的格式化顺序读写,通过DataOutputStream 向文件顺序写出 布尔值,整数和字符串。 然后再通过DataInputStream 顺序读入这些数据。
数据输入流和数据输出流都是依赖于其他流的

EOFException

要求DataInputStream 的文件必须由DataOutputStream 写出

File in_file = new File("d:/out.txt");
        File out_file = new File("d:/out.txt");
        try (
                FileInputStream fileInputStream = new FileInputStream(in_file);
                FileOutputStream fileOutputStream = new FileOutputStream(out_file);
                DataInputStream dataInputStream = new DataInputStream(fileInputStream);
                DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);
                ){

            dataOutputStream.writeBoolean(true);
            dataOutputStream.writeInt(312);
            dataOutputStream.writeUTF("hello world");
            boolean b = dataInputStream.readBoolean();
            int t = dataInputStream.readInt();
            String string = dataInputStream.readUTF();
            System.out.println(b);
            System.out.println(t);
            System.out.println(string);

对象流

对象流指的是可以直接把一个对象以流的形式传输给其他的介质,比如硬盘
一个对象以流的形式进行传输,叫做序列化。 该对象所对应的类,必须是实现Serializable接口
即必须有成员变量servialVersional
private static final long servialVersionUID =1L;

public class Hero implements Serializable {
    private static final long servialVersionUID =1L;
    public String name ;
    public float hp;
}

一般使用方法:

        Hero hero = new Hero();
        hero.name="garen";
        hero.hp=812;
        File file = new File("d:/garen.lol");
        try (
                FileOutputStream fileOutputStream = new FileOutputStream(file);
                ObjectOutputStream objectOutputStream=new ObjectOutputStream(fileOutputStream);
                FileInputStream fileInputStream=new FileInputStream(file);
                ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);

                ){
                    objectOutputStream.writeObject(hero);//首先将对象写入对象,之后将再将对象读出
                    Hero h2= (Hero)objectInputStream.readObject();
            System.out.println(h2.name);
            System.out.println(h2.hp);

小结

流分为字节流和字符流
字节流又分为数据流对象流
字符流常用的又有缓存流

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值