九、IO流
一、异常
概述:Java程序出现了不正常的现象
继承体系:
Throwable::
Error: 表示很严重的问题,一般情况下不解决
Exception:编译时期异常:写代码的过程,编译错误是不会产生class文件,一般情况下是因为我们自己的原因导致或者代码本身抛出了一个编译时期异常
RuntimeException(运行时期异常): 在java程序运行过程中出现的问题,一般是因为我们自己的原因导致
处理方案:①try.....catch......finally
try{
放可能会出错的代码;
}catch(Exception e){
处理的方式逻辑;
}finally{ // 可写可不写
无论如何都会执行的代码;(一般是释放资源的代码)
}
注意:
1、try中可以多写catch,如果catch中的异常类之间存在继承关系,请将父类异常写在最后一个catch中
2、可以使用|写在一个catch中,但是只能是平级关系
②throw:后面抛出的是异常类,抛给调用者,作用在方法上的
throw:是用在方法的内部,表示明确会出现某一个问题,配合着throws使用
今后遇到异常,直接使用try.....catch
异常类中的方法:
getMeaasge()
获取异常信息,返回字符串
toString()
获取异常类名和异常信息,返回字符串。
printStackTrace()
获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
二、File
概述:是文件与文件夹的抽象表示
构造方法:public File(String pathname) 以字符串路径的方式将文件或者文件夹封装成一个File对象
public File(String parent,String child) 根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例
public File(File parent,String child) 根据f 抽象路径名和 child 路径名字符串创建一个新 File 实例
路径:
绝对路径(完整路径):带有盘符的路径E:\projects\IdeaProjects\bigdata27\src\com\shujia\day12\a.txt
相对路径:src/com/shujia/day12/a.txt
成员方法:
①创建功能:public boolean createNewFile() 将文件创建出来,不是文件夹
public boolean mkdir() 创单级文件夹
public boolean mkdirs() 创多级文件夹
②删除功能:public boolean delete() 可以删除文件和文件夹,但是如果删除删除文件夹的话,要求文件夹中是空的
③重命名功能:public boolean renameTo(File dest) 重命名
④判断功能:public boolean isDirectory() 是否是一个文件夹
public boolean isFile() 是否是一个文件
public boolean exists() 是否存在
public boolean canRead() 是否可读
public boolean canWrite() 是否可写
public boolean isHidden() 是否隐藏
⑤基本获取功能:public String getAbsolutePath() 获取文件的绝对路径
public String getPath() 获取相对路径
public String getName() 获取名字
public long length() 获取字节数
public long lastModified() 获取最后一次修改时间 返回的是毫秒级别的时间戳
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(file.lastModified())));
⑥高级获取功能:public String[] list(): 将文件夹中的所有文件以及文件夹的名字获取出来,并封装成一个数组
public File[] listFiles(): 将文件夹中的所有文件以及文件夹都封装成File对象后,再封装成一个数组
⑦文件名称过滤器:public File[] listFiles(FilenameFilter filter)
package com.shujia.day12; import java.io.File; import java.io.FileFilter; import java.util.Arrays; /* 文件名称过滤器:FilenameFilter 判断E盘目录下是否有后缀名为.jpg的文件,如果有,就输出此文件名称 public File[] listFiles(FilenameFilter filter) */ public class FileDemo7 { public static void main(String[] args) { //将E盘封装成File对象 File file = new File("E:\\"); //public File[] listFiles(FilenameFilter filter) File[] files = file.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { // return true; return pathname.isFile() && pathname.getName().endsWith(".jpg");//判断E盘目录下是否有后缀名为.jpg的文件,如果有,就输出此文件名称 } }); System.out.println(Arrays.toString(files)); } }
三、递归
概述:方法定义中调用方法自身的现象
写递归的注意事项 1、要有开始条件 2、要有结束条件(出口),如果没有结束条件(出口),那么就是一个死递归,如果是死递归,容易造成栈内存 3、递归要有返回值
sb.append().append() 这不是递归,这叫方法链式调用
demo.fun1(fun2()) 这也不是递归,叫方法嵌套调用
四、IO流
分类:字节流、字符流
根据流向:
输入流:input 外部的数据 ---> Java
输出流:output Java ---> 外部文件中
字节缓冲流与字符缓冲流:
缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率。
如果只是想要刷新缓冲区中的数据,而不是关闭资源,建议使用flush(),每写一次,刷一次
public int read()一次读取一个字节 每调用一次read方法,光标会向后移动一位
public int read(byte[] b)一次读取一个字节数组
1、字节流(不适用于读汉字)
字节流分为字节输入流与字节输出流
①字节输入流:抽象父类:InputStream (读取的文件必须提前存在)
实现类1:FileInputStream 读取方式:一次读取一个字节、一次读取一个字节数组
实现类2:字节缓冲输入流 BufferedInputStream 读取方式:一次读取一个字节、一次读取一个字节数组
②字节输出流:抽象父类:OutputStream
实现类1:FileOutputStream 写数据的方式:一次写一个字节、一次写一个字节数组、一次写一个字节数组的一部分
public void write(int b) 写一个int类型的数,转成ASCII码写到文件中
public void write(byte[] b) 写一个字节数组
public void write(byte[] b,int off,int len) 将字节数组的一部分写到文件中
public FileOutputStream(String name, boolean append)传参的时候,可以加一个true,表示追加写入
实现类2:字节缓冲输出流 BufferedOutputStream 写数据的方式:一次写一个字节、一次写一个字节数组、一次写一个字节数组的一部分
2、字符流
字符流=字节流+编码表
使用场景:
字节流适用于任意格式的文件(图片,视频,文本文件,其他的)
字符流只适用于我们使用记事本打开能看懂的文件
①字符输入流:抽象父类:Reader
实现类1:InputStreamReader
构造方法:public InputStreamReader(InputStream in)
public InputStreamReader(InputStream in,String charsetName)
读取数据的方式: 一次读取一个字符、一次读取一个字符数组
子类:FileReader 读取数据的方式: 一次读取一个字符、一次读取一个字符数组
实现类2:字符缓冲输入流 BufferedReader 读取数据的方式: 一次读取一个字符、一次读取一个字符数组、一次读取一行
②字符输出流:抽象父类:Writer
实现类1:OutputStreamWriter
写数据的方式:一次写一个字符、一次写一个字符数组、一次写一个字符数组的一部分、一次写一个字符串、一次写一个字符串的一部分
子类:FileWriter 写数据的方式:一次写一个字符、一次写一个字符数组、一次写一个字符数组的一部分、一次写一个字符串、一次写一个字符串的一部分
3、IO流的使用
①:考虑使用字节流还是字符流 判断依据:如果使用记事本打开能看懂就用字符流,看不懂就用字节流
②:考虑是输入还是输出 判断依据:以java程序为中心
③:要不要快?如果要快,使用对应的缓冲流
④:无特殊情况下,字节流无脑选择字节缓冲流,字符流无脑选择字符缓冲流(简化写法的)
五、序列化
概述:序列化:将对象像数据流一样在网络中传输的过程
反序列化:将网络中传输的数据流转变成一个对象的过程
序列化流:
反序列化(对象输入流):ObjectInputStream
序列化(对象输出流):ObjectOutputStream
注意:
只有实现了Serializable接口的类创建出的对象才可以进行序列化,而Serializable接口是一个标记接口
我们在实现了序列化和反序列化的时候,改动了一下类的内容,结果报错了
InvalidClassException: com.shujia.day15.Student;
local class incompatible:
stream classdesc serialVersionUID = -5185173107402377683,
local class serialVersionUID = 7724834731532586360
原因:因为改动后的class中serialVersionUID与实际存储在文件中的对象serialVersionUID编号不一致
解决方案:只要保证无论怎么该class,它的serialVersionUID不变就可以了。自动生成即可
需求:我不想让年龄也进行序列化,java提供了一个关键字:transient 可以修饰成员,被修饰的成员无法进行序列化
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!