文章目录

  • JAVA part13 异常和IO流
  • 异常
  • 异常的默认处理方式
  • 编译时异常和运行时异常的区别
  • 异常处理的方案
  • try...catch...
  • throws
  • File类
  • File构造方法:
  • File类的创建功能
  • File类的删除功能
  • File类的判断和获取功能
  • IO流
  • FileOutputStream写数据
  • FileOutputStream写数据的三种方式
  • FileOutputStream实现换行和追加写入
  • FileOutputStream写数据加入异常处理
  • FileInputStream读取


JAVA part13 异常和IO流

异常

就是程序出现了不正常的情况

Throwable类是Java语言中有所错误或异常的超类

Error:
是Throwable的子类,用于指示合理的应用程序不应该试图捕获的严重问题。
也就是说针对程序发生了Error的情况,Java程序本身无能为力。比如说:硬件层面的问题,内存不足等。
所以,针对Error的问题我们不处理

Exception类:
Exception类及其子类是ThrowAble的一种形式,它指出了合理的应用程序想要捕获的条件。
也就是说针对程序发生了Exception的情况,是我们需要处理的。

RuntimeException:
是那些可能在Java虚拟机正常运行期间抛出的有i长的超类

Exception分为运行期和编译期:
1.运行期(RuntimeException)的异常:在编译期是不处理的,在程序运行出现了问题,休要我们回来修改代码。
2.编译期(非RuntimeException)的异常,在编译期就必须处理,否则程序不能通过编译,就更不能正常执行了。

异常的默认处理方式

如果程序出现了问题,我们没有做任何的处理,最终JVM会做出默认的处理。

处理方案:
1.把异常的名称,异常的原因,异常出现的位置等信息输出在控制台上
2.让程序停止执行

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

Java中的异常分为两大类:编译时异常和运行时异常

所有的RuntimeException类及其子类的实力被称为运行时异常,其他的异常都是编译时异常

编译时异常:Java程序必须显示处理,否则程序就会发生错误的一个提示,无法通过编译
运行时异常:Java程序无需显示处理,也可以和编译时异常一样处理。

package Day_13;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class test2 {
    public static void main(String[] args) {
        System.out.println("程序开始执行");
        method();
        method2();
        System.out.println("程序结束执行");
    }
    // 编译时异常
    public static void method(){
        try{
            String s = "2000-01-01";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date d = sdf.parse(s);
            System.out.println(d);
        }catch(ParseException e){
            e.printStackTrace();
        }
        System.out.println("------------------");
    }

    //运行时异常
    public static void method2(){
        try{
            int a = 10;
            int b = 0;
            System.out.println(a/b);
        }catch(ArithmeticException e){
            e.printStackTrace();
        }
    }
}

异常处理的方案

try…catch…

格式:

try{
        可能出现异常的代码;
    }catch(异常类名 变量名){
        异常的处理代码;
    }

执行流程:
程序从try开始执行,执行到哪里出现了问题,就会跳转到catch里面执行
执行完毕后,程序还能继续往下执行

代码:

package Day_13;

public class test1 {
    public static void main(String[] args) {
        System.out.println("程序开始执行");
        method();
        System.out.println("程序结束执行");
    }
    public static void method(){
        try{
            int a = 10;
            int b = 0;
            System.out.println(a/b);
            System.out.println("节点A");//发生异常,节点A不输出
        }catch(ArithmeticException e){
            System.out.println("除数不能为0");
        }
        System.out.println("节点B");
    }
}

public void printStackTrace():
把异常的错误输出在控制台。

package Day_13;

public class test1 {
    public static void main(String[] args) {
        System.out.println("程序开始执行");
        method();
        System.out.println("程序结束执行");
    }
    public static void method(){
        try{
            int a = 10;
            int b = 0;
            System.out.println(a/b);
        }catch(ArithmeticException e){
            e.printStackTrace();
        }
    }
}

输出结果为:

程序开始执行
java.lang.ArithmeticException: / by zero
	at Day_13.test1.method(test1.java:13)
	at Day_13.test1.main(test1.java:6)
程序结束执行
throws

通常我们通过try…catch…对异常进行处理,但并不是所有的时候都有权限进行异常的处理。也就是说有些时候我们处理不了但这个时候异常是存在的,就需要使用Java提供的throws的处理方案

格式:

throws 异常类名

tips:
这个格式必须跟在方法的括号后面

代码:

package Day_13;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class test3 {
    public static void main(String[] args) throws ParseException {
        System.out.println("程序开始执行");
        method();
        method2();
    }
    // 编译时异常
    public static void method() throws ParseException {
        String s = "2000-01-01";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date d = sdf.parse(s);
        System.out.println(d);
    }
    //运行时异常
    public static void method2() throws ArithmeticException{
        int a = 10;
        int b = 0;
        System.out.println(a/b);
    }
}

tips:
1.编译时异常是必须要处理的,两种处理方法:try…catch…或者throws
如果你采用了throws这种方案,将来谁调用,还得进行处理
2.运行时异常可以不用处理,出现问题后回来该代码即可

File类

File:文件和目录路径名的抽象表示形式
也就是说文件和目录时可以通过File封装乘对象的
目录:就是文件夹

File构造方法:

1.File(String pathname):通过将给定路径名字符串转换为抽象路径名来创建一个新File实例。
2.File(String parent, String child):根据parent路径名字符串和child路径名字符串创建一个新File实例
3.File(File parent, String child):根据parent抽象路径名和child路径名字符串创建一个新File实例

package Day_13;

import java.io.File;

public class test4 {
    public static void main(String[] args) {
        //File(String pathname)
        File f1 = new File("d:\\aa\\b.txt");
        //File(String parent, String child)
        File f2 = new File("d:\\aa", "b.txt");
        //File(File parent, String child)
        File f3 = new File("d:\\aa");
        File f4 = new File(f3, "b.txt");
        
        //上面的f1,f2,f4其实做的时同样的事,就是把d:\\aa\\b.txt转换为了一个File对象
    }
}

File类的创建功能

创建功能:
1.public boolean createNewFile():创建文件
如果文件不存在,创建文件并返回true
如果文件存在,创建文件失败并返回false
2.public boolean mkdir():创建目录
如果目录不存在,创建目录并返回true
如果目录存在,创建目录失败并返回false
3.public boolean mkdirs():创建多级目录

代码:

package Day_13;

import java.io.File;
import java.io.IOException;

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

        //public boolean createNewFile()创建文件
        File f1 = new File("d:\\a.txt");
        System.out.println("creatNewFile:"+f1.createNewFile());
        //public boolean mkdir()创建目录
        File f2 = new File("d:\\bb");
        System.out.println("mkdir:"+f2.mkdir());
        //public boolean mkdirs()创建多级目录
        File f3 = new File("d:\\cc\\dd");
        System.out.println("mkdirs:"+f3.mkdirs());
    }
}

File类的删除功能

删除功能:
public boolean delete():删除文件和目录

路径问题:
1.绝对路径:是以盘符开始的路径。d:\aa\b.txt
2.相对路径:不以盘符开始,相对于当前的项目而言,在项目的额目录下。

tips:
如果一个目录中有内容(目录、文件)就不能直接删除,需要先删除目录中的内容,再删除内容

代码:

package Day_13;

import java.io.File;
import java.io.IOException;

public class test6 {
    public static void main(String[] args) throws IOException {
        //删除a.txt文件
        File f1 = new File("a.txt");
        System.out.println("delete:"+f1.delete());

        //删除无内容的bb目录
        File f2 = new File("bb");
        System.out.println("delete:"+f2.delete());

        //删除有内容的cc目录
        File f3 = new File("cc//dd.txt");
        System.out.println("delete:"+f3.delete());
    }
}

File类的判断和获取功能

判断功能:
public boolean isDirectory():判断是否是目录
public boolean isFile():判断是否是文件
public boolean exists():判断是否存在
获取功能:
public String getAbsolutePath():获取绝对地址
public String getPath():获取相路径
public String getName():获取名称

代码:

package Day_13;

import java.io.File;

public class test7 {
    public static void main(String[] args) {
        
        //创建File对象
        File f = new File("aaa\\bbb.txt");
        
        //判断功能
        System.out.println("isDirectory:"+f.isDirectory());
        System.out.println("isFile:"+f.isFile());
        System.out.println("exists:"+f.exists());
        System.out.println("------------");
        
        //获取功能
        System.out.println("getAbsolutePath:"+f.getAbsolutePath());
        System.out.println("getPath:"+f.getPath());
        System.out.println("getName:"+f.getName());
    }
}

IO流

是用来处理设备间数据传输问题的

常见的应用:
文件复制
文件上传
文件下载

IO流分类:
输入流、输出流
输入流即为读数据
输出流即为写数据

数据类型:
字节流输入流、字节流输出流
字符流输入流、字符流输出流
字符流数据通过windows系统自带的 记事本软件打开时可以读懂里面的内容的

FileOutputStream写数据

字节流:
InputStream 字节输入流
OutputSteam 字节输出流

字符流:
Reader 字符输入流
Writer 字节输出流

字节流写数据:
OutputSteam:此抽象类时表示输出字节流的所有类的超类
FileOutputStream:文件输出流时用于将数据写入File

构造方法:
FileOutputStream(String name):创建一个想具有指定名称的文件中写入数据的输出文件流

创建字节输出流对象做了三件事:
1.调用系统功能创建了文件
2.创建字节输出流对象
3.让fos这个对象指向a.txt这个文件

字节流写数据的步骤:
1.创建字节输出流对象
2.调用写数据的方法
3.释放资源

代码:

package Day_13;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

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

        //创建字节输出流对象
        FileOutputStream fos = new FileOutputStream("a.txt");

        //write(int b)
        fos.write(65);
        fos.write(66);
        
        //释放资源
        fos.close();
    }
}
FileOutputStream写数据的三种方式

构造方法:
FileOutputStream(String name)
FileoutputSteam(File file)

public void write(int b):一次写一个字节
public void write(byte[ ] b):一次写一个字节数组
public void write(byte[ ] b, int off, int len):一次写一个字节数组的一部分

public void write(int b):一次写一个字节

package Day_13;

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

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

        //创建字节输出流对象
        //FileOutputStream(String name)
        FileOutputStream fos = new FileOutputStream("b.txt");

        //public void write(int b):一次写一个字节
        fos.write(65);
        
        //释放资源
        fos.close();
    }
}

public void write(byte[ ] b):一次写一个字节数组

package Day_13;

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

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

        //创建字节输出流对象
        //FileOutputStream(String name)
        FileOutputStream fos = new FileOutputStream("b.txt");

        //public void write(byte[ ] b):一次写一个字节数组
        byte[] bys = {65, 66, 67, 68, 69};
        fos.write(bys);
        
        //写一个字符串数组
        fos.write("ABCDE".getBytes());

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

public void write(byte[ ] b, int off, int len):一次写一个字节数组的一部分

package Day_13;

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

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

        //创建字节输出流对象
        //FileOutputStream(String name)
        FileOutputStream fos = new FileOutputStream("b.txt");

        //public void write(byte[ ] b, int off, int len):一次写一个字节数组的一部分
        fos.write("ABCDE".getBytes(),0, 3);
        
        //释放资源
        fos.close();
    }
}
FileOutputStream实现换行和追加写入

实现换行:
不同的操作系统针对换行的符号识别时不一样的:
windows: \r\n
linux: \n
mac: \r

实现数据的追加写入:
用构造方法第二个参数是true的情况即可

代码:

package Day_13;

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

public class test10 {
    public static void main(String[] args) throws IOException {
        
        //创建字节输出流对象,如果第二个参数为true,则将他字节写入文件末尾处,而不是写入文件开始处
        FileOutputStream fos = new FileOutputStream("c.txt", true);
        
        //调用写数据的方法
        for(int x=0; x<10; x++){
            fos.write("hello".getBytes());
            //加入换行符号
            fos.write("\r\n".getBytes());
        }
        //释放资源
        fos.close();
    }
}
FileOutputStream写数据加入异常处理
package Day_13;

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

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

        FileOutputStream fos = null;

        try{
            fos = new FileOutputStream("d.txt");
            fos.write("hello".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(fos != null);{
                try{
                    fos.close();
                }catch(IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
}
FileInputStream读取

读取方式分两种:
1.一次读取一个字节:

package Day_13;

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

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

        FileInputStream fis = new FileInputStream("a.txt");

        int by;
        while((by=fis.read()) != -1);{
            System.out.println((char)by);
        }
        fis.close();
    }
}

2.一次读取一个字节数组:

package Day_13;

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

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

        FileInputStream fis = new FileInputStream("b.txt");

        byte[] bys = new byte[1024];//1024或1024的整数倍
        int len;
        while((len=fis.read(bys)) != -1){
            System.out.println(new String(bys, 0, len));
        }
        fis.close();
    }
}