当前位置: 首页 > news >正文

Java阶段一Day19

Java阶段一Day19

文章目录

对象流

java.io.ObjectlnputStreamObjectOutputStream

作用

  • 对象输出流:将我们的java对象进行序列化
  • 对象输入流:将java对象进行反序列化

序列化
将一个对象转换为一组可被传输或保存的字节。这组字节中除了包含对象本身的数据外,还会包含结构信息。

反序列化

将字符序列还原回一个对象的过程
在这里插入图片描述

transient:短暂的

有时候,一些对象的状态没必要写入和读取,使用transient,被transient关键字修饰后,该对象在进行序列化时,转换出来的字节中不包含该属性,忽略不必要属性达到对象“瘦身”操作

对象瘦身可以在对象持久化时减少磁盘开销。在进行传输时可以缩短传输速度。

如果该对象,不需要序列化,那么该关键字不发挥任何效果

读写数据的单位分为 字符流和字节流

字符流

  • 都是高级流,ReaderWriter
  • java.io. Reader是字符输入流的父类
  • java.io. Writer是字符输出流的父类。
  • 字符流是以字符(char)为单位读写数据的。一次处理一个unicode。
  • 字符流的底层仍然是基本的字节流。

Writer

常用方法:

方法介绍
void write(int c)写出一个字符,写出给定int值"低16”的字符
void write(char[] chs)将给定字符数组中所有字符写出
void write(String str):将给定的字符串写出
void write(chang] chs,int offsetint len)给定的字符数组中从offset处开始连续的len个字符写出

Reader

常用方法:

方法介绍
int read()读取一个字符,返回的int值“低16”位有效
int read(char[] chs)从该流中读取一个字符数组的length个字符并存入该数组,返回值为实际读取到的字符量

转换流

字符流和字节流不能直接连接,需要转换流

在这里插入图片描述

  • InputStreamReader:字符输入流。

    • 使用该流可以设置字符集,并按照指定的字符集从流中按照该编码将字节数据转换为字符并读取。

    • lnputStreamReader的构造方法:

      方法介绍
      lnputStreamReader(InputStream in,Charset cs)基于给定的字节输入流以及字符编码创建ISR
      InputStreamReader(InputStream in)该构造方法会根据系统默认字符集创建ISR
  • OutputStreamWriter:字符输出流

    • 使用该流可以设置字符集,并按照指定的字符集将字符转换为对应字节后通过该流写出。

    • OutputStreamWriter的构造方法:

      方法介绍
      OutputStreamWriter(OutputStream out,Charsetcs)基于给定的字节输出流以及字符编码创建OSW
      OutputStreamWriter(OutputStream out)该构造方法会根据系统默认字符集创建OSW
  • 意义:

    • 转换流是唯一可以连接在字节流上的字符流。而其他字符流都只能连接在字符流上。

    • 因此在流连接中我们使用的字符流只有先连接在转换流上才能再连接到字节流上进行工作。所以转换流起到了转换器的作用。

缓冲字符流

  • java.io.BufferedWriterBufferedReader
    • 缓冲字符流内部有一个默认为8192长度的char数组,总是以块读写形式来保证读写效率。
  • java.io.PrintWriter
    • 具有自动行刷新功能的缓冲字符输出流,内部总是连接BufferedWriter作为缓冲使用。

特点:

  • 可以按行写出字符串
  • 可选的自动行刷新功能

BufferedWriter与PrintWriter

  • PrintWriter是具有自动行刷新的缓冲字符输出流。其提供了比较丰富的构造方法。

    • PrintWriter(File file)
    • PrintWriter(String fileName)
    • PrintWriter(OutputStream out)
    • PrintWriter(OutputStream out,boolean autoFlush)
    • PrintWriter(Writer writer)
    • PrintWriter(Writer writer,boolean autoFlush)
    • 传入boolean值参数,用于表示PrintWriter是否具有自动行刷新
  • PrintWriter提供了丰富的重载print与println方法。其中println方法在于输出目标数据后自动输出一个系统支持的换行符。

  • 若该流是具有自动行刷新的,那么每当通过println方法写出的内容都会被实际写出,而不是进行缓存。

  • 常用方法:

    方法介绍
    void printIn(int i)打印整数
    void printIn(char c)打印字符
    void printIn(boolean b)打印boolean值
    void printIn(char[] c)打印字符数组
    void printIn(double d)打印double值
    void printIn(float f)打印float值
    void println(long l)打印long值
    void println(String str)打印字符串

在文件输出流上最终链接到PrintWriter

在这里插入图片描述

public static void main(String[] args) throws IOException {//四层流连接//fos -> osw -> bw -> pw//负责:将写出的字节写入文件中FileOutputStream fos = new FileOutputStream("text2.txt",true);//负责:将写出的字符全部转换成字节(可指定字符集转换)OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);//负责:块写入数据(攒够8192个字符一次性写出)BufferedWriter bw = new BufferedWriter(osw);//负责:按行输出字符串PrintWriter pw = new PrintWriter(bw,true);pw.println("这是一个测试语句");pw.println("这是另一个测试语句");System.out.println("写出完毕");pw.close();}

BufferedReader

  • 缓冲字符输入流:java.io. BufferedReader
  • 缓冲字符输入流内部默认有一个长度为8192的char数组,块读文本数据加速。
  • 并且其还具备按行读取字符串的能力
    • String readLine()
    • 该方法连续读取一行字符串,直到读取到换行符为止,返回的字符串中不包含该换行符。
  • BufferedReader的常用构造方法:
    • BufferedReader(Reader reader)
public static void main(String[] args) throws IOException {/** 一口气读8192个字符*  readLine(new String)* 在其内部扫描,遇到换行就输出换行符前的内容* 下次从换行符之后出发直到下一个换行符* 该行没内容就返回 " " 表示空行 * 文件判断结束末尾是null*/// 三次链接  fis -> isr -> br//负责:读取文件中的字节FileInputStream fis = new FileInputStream("./src/main/java/com/liner/io/BRDemo.java");//负责:将读取的字符全部转换成字节InputStreamReader isr = new InputStreamReader(fis);//负责:块读取数据(攒够8192个字符一次性读取)BufferedReader br = new BufferedReader(isr);String line;//readLine检测到/n自动换行 while ((line = br.readLine()) != null) {System.out.println(line);}br.close();}

异常

Throwable、Error、Exception

  • Java异常结构中定义有Throwable类,Exception和Error是其派生的两个子类。
    • Exception表示由于网络故障、文件损坏、设备错误、用户输入非法等情况导致的异常,可恢复
    • Error表示Java运行时环境出现的错误,例如:JVM内存资源耗尽等。不可恢复

异常处理机制

程序抛出异常,程序从导致异常的代码处跳出,jjava虚拟机检测寻找和try关键字匹配的处理该异常的catch块

如果找到,将控制权交到catch块中的代码,然后继续往下执行程序,try块中发生异常的代码不会被重新执行。

如果没有找到处理该异常的catch块,在所有的finally块代码被执行和当前线程的所属的ThreadGroup的uncaughtException方法被调用后,遇到异常的当前线程被中止。

throw

  • 当程序发生错误而无法处理的时候,会抛出对应的异常对象
  • 在某些时刻,可能会想要自行抛出异常,并生成指定的异常对象后抛出

throws

  • 程序中会声明许多方法(Method),可能会因某些错误而引发异常
  • 不希望直接在这个方法中处理这些异常,而希望调用这个它的方法来统一处理
  • 重写方法时的throws
    • 使用继承时,在父类别的某个方法上宣告了throws某些异常,而在子类别中重新定义该方法时,可以:
      • 不处理异常(重新定义时不设定throws)
      • 可仅throws父类别中声明的部分异常。
      • 可throws父类方法中抛出异常的子类异常
    • 但是不可以:
      • throws出额外的异常
      • throws父类方法中抛出异常的父类异常

try-catch

  • 就是一次捕获并处理例外的范围
  • 在执行过程中,该段代码可能会产生并抛出一种或几种类型的异常对象,它后面的catch语句分别对这些异常做相应的处理
  • 如果没有异常产生,所有的catch代码段都被略过不执行
  • 当多个异常可使用同一种方法解决时,可以合并到一个catch中处理
  • 在catch语句块中是对异常进行处理的代码
  • 在catch中声明的异常对象(catch(SomeExceptione))封装了异常事件发生的信息,
  • 在catch语句块中可以使用这个对象的一些方法获取这些信息

finally

  • finally语句为异常处理提供一个统一的出口,使得在控制流程转到程序其它部分以前,能够对程序的状态作统一管理

  • 无论try所指定的程序块中是否抛出异常,finally所指定的代码都要被执行

  • 通常在finally语句中可以进行资源的释放工作,如关闭打开的文件、删除临时文件等。

  • JDK7之后,java推出了自动关闭特性,旨在更优雅的在异常处理机制中关闭如流这样的操作

    //只有实现了java.io.AutoCloseable接口的类才可以在这里定义
    //在try的()中定义并初始化需要在finally中调用close方法的对象
    //自动关闭特性是编译器认可的
    public static void main(String[] args) {try (FileOutputStream fos = new FileOutputStream("fos.dat");) {fos.write(1);} catch (IOException e) {e.printStackTrace();}}
    

面试题

请分别描述final,finally ,finalize?

  • final:最终的,最后的,被final修饰的类不可被继承,被修饰的变量是不可变量,被修饰的方法不可被重写
  • finally:在try-catch代码块的最后加上finally,为异常处理提供一个统一的出口
  • finalize是Object定义的一个方法,java中所有的类都有这个方法。
    • 特点:该方法是一个对象声明周期的最后一个方法。当GC发现一个对象没有引用时就会释放该对象,释放前会调用该对象的finalize方法,该方法调用后,对象被销毁

教师总结

新单词

  • transient-稍纵即逝的

  • unsupported-不支持的

  • encoding-编码

  • try-试试

  • **catch-**抓住,捕获

  • throw-抛出,扔出

  • error-错误

  • AutoClose-自动关闭

JAVA IO

对象流

对象输入流

java.io.ObjectInputStream使用对象流可以进行对象反序列化

构造器
ObjectInputStream(InputStream in)
将当前创建的对象输入流链接在指定的输入流上   
方法
Object readObject()
进行对象反序列化并返回。该方法会从当前对象输入流链接的流中读取若干字节并将其还原为对象。这里要注意读取的字节必须是由ObjectOutputStream序列化一个对象所得到的字节。
package io;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;/*** 对象输入流,用来进行对象反序列化*/
public class OISDemo {public static void main(String[] args) throws IOException, ClassNotFoundException {//读取person.obj文件并将其中保存的数据进行反序列化FileInputStream fis = new FileInputStream("person.obj");ObjectInputStream ois = new ObjectInputStream(fis);Person person = (Person)ois.readObject();System.out.println(person);ois.close();}
}
transient关键字

当一个属性被transient关键字修饰后,该对象在进行序列化时,转换出来的字节中是不包含该属性的。忽略不必要的属性可以达到对象"瘦身"的操作。

对象瘦身可以在对象持久化时减少磁盘开销。在进行传输时可以缩短传输速度。

如果该对象不需要序列化,那么该关键字不发挥其他任何效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Av9gHF24-1681122832913)(C:\Users\TEACHER\IdeaProjects\JSD2303_SE\笔记\image-20230410093231602.png)]

序列化时不包含otherInfo属性,并且反序列化时该属性值为null
在这里插入图片描述

字符流

  • java将流按照读写单位划分为字节流与字符流.
  • java.io.InputStream和OutputStream是所有字节流的超类
  • 而java.io.Reader和Writer则是所有字符流的超类,它们和字节流的超类是平级关系.
  • Reader和Writer是两个抽象类,里面规定了所有字符流都必须具备的读写字符的相关方法.
  • 字符流最小读写单位为字符(char),但是底层实际还是读写字节,只是字符与字节的转换工作由字符流完成.
  • 字符流都是高级流

超类

  • java.io.Writer 所有字符输入流的超类

    常用方法

    void write(int c):写出一个字符,写出给定int值”低16”位表示的字符。
    void write(char[] chs):将给定字符数组中所有字符写出。
    void write(String str):将给定的字符串写出
    void write(char[] chs,int offset,int len):将给定的字符数组中从offset处开始连续的len个字符写出
    
  • java.io.Reader 所有字符输出流的超类

    常用方法

    int read():读取一个字符,返回的int值“低16”位有效。当返回值为-1时表达流读取到了末尾。
    int read(char[] chs):从该流中读取一个字符数组的length个字符并存入该数组,返回值为实际读取到的字符量。当返回值为-1时表达流读取到了末尾。

转换流

java.io.InputStreamReader和OutputStreamWriter是常用的字符流的实现类。

实际开发中我们不会直接操作他们,但是他们在流连接中是必不可少的一环。

流连接中的作用
  • 衔接字节流与其他字符流
  • 将字符与字节相互转换
意义

实际开发中我们还有功能更好用的字符高级流.但是其他的字符高级流都有一个共通点:不能直接连接在字节流上.而实际操作设备的流都是低级流同时也都是字节流.因此不能直接在流连接中串联起来.转换流是一对可以连接在字节流上的字符流,其他的高级字符流可以连接在转换流上.在流连接中起到"转换器"的作用(负责字符与字节的实际转换)

输出流
构造器
OutputStreamWriter(OutputStream out,Charset cs)
基于给定的字节输出流以及字符编码创建OSWOutputStreamWriter(OutputStream out)
该构造方法会根据系统默认字符集创建OSW

示意

在这里插入图片描述

package io;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;/*** 转换流写出文本数据*/
public class OSWDemo {public static void main(String[] args) throws IOException {//向文件osw.txt中写出文本数据FileOutputStream fos = new FileOutputStream("osw.txt");OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);osw.write("夜空中最亮的星,能否听清,");osw.write("那仰望的人心底的孤独和叹息。");System.out.println("写出完毕");osw.close();}
}
输入流
构造器
InputStreamWriter(InputStream in,Charset cs)
基于给定的字节输入流以及字符编码创建当前转换流InputStreamWriter(InputStream in)
该构造方法会根据系统默认字符集创建当前转换流

package io;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;/*** 使用转换流读取文本数据*/
public class ISRDemo {public static void main(String[] args) throws IOException {//将osw.txt文件中的文本信息读取回来FileInputStream fis = new FileInputStream("osw.txt");InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);//00000000 00000000 10011101 01110010int d;while(( d = isr.read()) != -1) {System.out.print((char) d);}isr.close();}
}

缓冲字符流

缓冲字符输出流-java.io.PrintWriter

  • java.io.BufferedWriter和BufferedReader

  • 缓冲字符流内部也有一个缓冲区,读写文本数据以块读写形式加快效率.并且缓冲流有一个特别的功能:可以按行读写文本数据.缓冲流内部维护一个char数组默认长度8192.以块读写方式读写字符数据保证效率

  • java.io.PrintWriter具有自动行刷新的缓冲字符输出流,实际开发中更常用.它内部总是会自动连BufferedWriter作为块写加速使用.

工作原理

在这里插入图片描述

特点

  • 可以按行写出字符串

  • 具有自动行刷新功能

对文件写操作的构造器
PrintWriter(File file)
PrintWriter(String path)还支持指定字符集
PrintWriter(File file,String csn)
PrintWriter(String path,String csn)  上述构造器看似PW可以直接对文件进行操作,但是它是一个高级流,实际内部会进行流连接:
this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))),false);
如上面工作原理图
package io;import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;/*** 缓冲字符输出流:java.io.PrintWriter* 特点:* 1:按行写出字符串* 2:具有自动的行刷新功能**/
public class PWDemo {public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {//向文件中写入文本数据/*PrintWriter(File file)PrintWriter(String path)*/PrintWriter pw = new PrintWriter("pw.txt");
//        PrintWriter pw = new PrintWriter("pw.txt", "UTF-8");pw.println("我祈祷拥有一颗透明的心灵,和会流泪的眼睛。");pw.println("给我再去相信的勇气,oh越过黄昏去拥抱你。");System.out.println("写出完毕");pw.close();}
}
其他构造器
PritWriter(Writer writer)
将当前实例化的PrintWriter链接在指定的字符输出流上    PrintWriter(OutputStream out)    
将当前实例化的PrintWriter链接在指定的字节输出流上
由于除了转换流外的其他字符流都不能直接连在字节流上,因此这个构造器内部会自动链接在BufferedWriter上
并且让BufferedWriter链接在转换流OutputStream上,最后再让转换流链接再指定的字节输出流上
package io;import java.io.*;
import java.nio.charset.StandardCharsets;/***  自行完成流连接向文件写出字符串*/
public class PWDemo2 {public static void main(String[] args) throws FileNotFoundException {//负责:将写出的字节写入到文件中FileOutputStream fos = new FileOutputStream("pw2.txt");//负责:将写出的字符全部转换为字节(可以按照指定的字符集转换)OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);//负责:块写文本数据(攒够8192个字符一次性写出)BufferedWriter bw = new BufferedWriter(osw);//负责:按行写出字符串PrintWriter pw = new PrintWriter(bw);pw.println("你停在了这条我们熟悉的街,");pw.println("把你准备好的台词全念一遍。");System.out.println("写出完毕");pw.close();}
}
自动行刷新

PrintWriter支持自动行刷新,每当我们调用println方法写出一行内容后自动flush一次。

对应的构造器
PritWriter(Writer writer,boolean autoflush)
如果第二个参数为true则开启自动行刷新 

package io;import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;/*** 实现一个简易的记事本工具* 利用流连接* 在文件输出流上最终链接到PrintWriter上。* 然后将用户在控制台上输入的每一行字符串都可以按行写入到对应的文件中。* 当用户在控制台上单独输入"exit"时程序退出。*/
public class AutoFlushDemo {public static void main(String[] args) throws FileNotFoundException {//负责:将写出的字节写入到文件中FileOutputStream fos = new FileOutputStream("note.txt");//负责:将写出的字符全部转换为字节(可以按照指定的字符集转换)OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);//负责:块写文本数据(攒够8192个字符一次性写出)BufferedWriter bw = new BufferedWriter(osw);//负责:按行写出字符串PrintWriter pw = new PrintWriter(bw,true);//开启自动行刷新Scanner scanner = new Scanner(System.in);System.out.println("请开始输入内容,单独输入exit退出");while(true){String line = scanner.nextLine();//String可以忽略大小写比较字符串内容:equalsIgnoreCaseif("exit".equalsIgnoreCase(line)){break;}pw.println(line);//每当println后自动flush。注意:print方法并不会自动flush}System.out.println("再见!");pw.close();}
}

缓冲字符输入流-java.io.BufferedReader

缓冲字符输入流内部维护一个默认8192长度的char数组,总是以块读取文本数据保证读取效率。

缓冲输入流提供了一个按行读取文本数据的方法

String readLine()
返回一行字符串。方法内部会连续扫描若干个字符,直到遇到换行符为止,将换行符之前的内容以一个字符串形式返回。
返回的字符串中不含有最后的换行符。
返回值有三种情况:
1:正常一行内容
2:空字符串。当读取了一个空行时(这一行只有一个换行符)3:null。当流读取到了末尾时。  当我们第一次调用readLine()时,流并不是只读取了一行字符串,而是先进行块读操作(一次性读取8192个字符并转入到内部的char数组中),然后扫描内部的char数组,然后将第一行字符串返回。第二次调用后再继续扫描后去的内容以此类推。    
package io;import java.io.*;/*** 使用缓冲字符输入流读取文本数据*/
public class BRDemo {public static void main(String[] args) throws IOException {//将当前源代码输出到控制台上/*1:创建文件输入流读取当前源代码文件2:进行流连接最终链接到BufferedReader上3:读取每一行字符串并输出到控制台上*/FileInputStream fis = new FileInputStream("./src/main/java/io/BRDemo.java");InputStreamReader isr = new InputStreamReader(fis);BufferedReader br = new BufferedReader(isr);String line;while((line = br.readLine())!=null) {System.out.println(line);}br.close();}
}

IO总结

在这里插入图片描述

JAVA 异常处理

java异常处理机制

  • java中所有错误的超类为:Throwable。其下有两个子类:Error和Exception
  • Error的子类描述的都是系统错误,比如虚拟机内存溢出等。
  • Exception的子类描述的都是程序错误,比如空指针,下表越界等。
  • 通常我们程序中处理的异常都是Exception。

在这里插入图片描述

try-catch

package exception;/*** 异常处理机制中的try-catch* 语法:* try{*     代码片段...* }catch(XXXException e){*     出现错误后的补救措施(B计划)* }*/
public class TryCatchDemo {public static void main(String[] args) {System.out.println("程序开始了...");/*try{}语句块不能单独写,后面要么跟catch语句块要么跟finally语句块异常处理机制关注的是:明知道程序可能出现某种错误,但是该错误无法通过修改逻辑完全规避掉时,我们会使用异常处理机制,在出现该错误是提供一种补救办法。凡是能通过逻辑避免的错误都属于bug!就应当通过逻辑去避免!*/try {
//            String str = null;
//            String str = "";String str = "a";/*若str=null的情况当JVM执行到下面代码时:str.length()会出现空指针,此时虚拟机就会根据该情况实例化一个对应的异常实例出来,即:空指针异常实例 NullPointerException实例然后将程序从一开始执行到报错这句话的过程设置到该异常实例中,此时该异常通过类型名字可以表达出现了什么错误,并将来可以通过输出错误信息来得知错误出现在那里虚拟机会将该异常抛出当某句代码抛出了一个异常时,JVM会做如下操作:1:检查报错这句话是否有被异常处理机制控制(有没有try-catch)如果有,则执行对应的catch操作,如果没有catch可以捕获该异常则视为没有异常处理动作2:如果没有异常处理,则异常会被抛出当当前代码所在的方法之外由调用当前方法的代码片段处理该异常*/System.out.println(str.length());//抛出空指针异常System.out.println(str.charAt(0));System.out.println(Integer.parseInt(str));/*当try中某句代码报错后,就会跳出try执行下面对应的catch块,执行后就会退出catch继续向后执行。因此try语句块中报错代码以下的内容都不会被执行*/System.out.println("!!!!!!!!!!!!!!");
//        }catch(NullPointerException e){
//            //这里实际开发中是写补救措施的,通常也会将异常信息输出便于debug
//            System.out.println("出现了空指针,并解决了!");
//        }catch(StringIndexOutOfBoundsException e){
//            System.out.println("处理字符串下标越界问题!");
//        }/*当try语句块中可能出现的几种不同异常对应的处理办法相同时,可以采取合并catch的做法,用同一个catch来捕获这几种可能出现的异常,而执行措施使用同一个。*/}catch(NullPointerException|StringIndexOutOfBoundsException e){System.out.println("处理空指针或下标越界!");/*当catch捕获某个超类型异常时,那么try语句块中出现它类型异常时都可以被这个catch块捕获并处理。如果多个catch捕获的异常之间存在继承关系时,一定是子类异常在上超类异常在下*/}catch(Exception e){System.out.println("反正就是出了个错!");}System.out.println("程序结束了...");}
}

finally块

finally块是异常处理机制中的最后一块

  • finally可以直接跟在try语句块之后
  • finally可以跟在最后一个catch块之后
  • fianlly下面不能再定义catch块

特点:

只要程序执行到异常处理机制中(执行到try语句块中),无论try中的代码是否出现异常,finally最终都必定执行

作用:

通常用来执行释放资源这一类操作。例如IO操作完毕后的流关闭。

package exception;/*** finally块*/
public class FinallyDemo {public static void main(String[] args) {System.out.println("程序开始了");try {String str = "null";System.out.println(str.length());return;//结束方法,结束前finally还是要执行的} catch (Exception e) {System.out.println("出错了");}finally {System.out.println("finally中的代码执行了");}System.out.println("程序结束了");}
}

在IO中的应用

package exception;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;/*** 异常处理机制在IO中的应用*/
public class FinallyDemo2 {public static void main(String[] args) {FileOutputStream fos = null;try {fos = new FileOutputStream("./fos.dat");fos.write(1);} catch (IOException e) {System.out.println("出错了");} finally {try {if(fos!=null) {fos.close();}} catch (IOException e) {e.printStackTrace();}}}
}

自动关闭特性

JDK7之后java推出了一个新特性:自动关闭特性可以更优雅的在异常处理机制中关闭IO

语法

try(声明并初始化IO对象
){IO操作
}catch(IOException e){//catch各种IO异常...
}

package exception;import java.io.FileOutputStream;
import java.io.IOException;/*** JDK7之后java推出了一个新特性:自动关闭特性* 可以更优雅的在异常处理机制中关闭IO*/
public class AutoCloseableDemo {public static void main(String[] args) {//自动关闭特性是编译器认可的,编译后就变成FinallyDemo2的样子try(FileOutputStream fos = new FileOutputStream("fos.dat");){fos.write(1);} catch (IOException e) {e.printStackTrace();}}
}

总结

java将流分为两类:节点流与处理流:
  • 节点流:也称为低级流.

    节点流的另一端是明确的,是实际读写数据的流,读写一定是建立在节点流基础上进行的.

  • 处理流:也称为高级流.

    处理流不能独立存在,必须连接在其他流上,目的是当数据流经当前流时对数据进行加工处理来简化我们对数据的该操作.

实际应用中,我们可以通过串联一组高级流到某个低级流上以流水线式的加工处理对某设备的数据进行读写,这个过程也成为流的连接,这也是IO的精髓所在.

缓冲流

缓冲流是一对高级流,在流链接中链接它的目的是加快读写效率。缓冲流内部默认缓冲区为8kb,缓冲流总是块读写数据来提高读写效率

java.io.BufferedOutputStream缓冲字节输出流,继承自java.io.OutputStream

常用构造器
  • BufferedOutputStream(OutputStream out):创建一个默认8kb大小缓冲区的缓冲字节输出流,并连接到参数指定的字节输出流上。
  • BufferedOutputStream(OutputStream out,int size):创建一个size指定大小(单位是字节)缓冲区的缓冲字节输出流,并连接到参数指定的字节输出流上。
常用方法
flush():强制将缓冲区中已经缓存的数据一次性写出缓冲流的写出方法功能与OutputStream上一致,需要知道的时write方法调用后并非实际写出,而是先将数据存入缓冲区(内部的字节数组中),当缓冲区满了时会自动写出一次。

java.io.BufferedInputStream缓冲字节输出流,继承自java.io.InputStream

常用构造器
  • BufferedInputStream(InputStream in):创建一个默认8kb大小缓冲区的缓冲字节输入流,并连接到参数指定的字节输入流上。
  • BufferedInputStream(InputStream in,int size):创建一个size指定大小(单位是字节)缓冲区的缓冲字节输入流,并连接到参数指定的字节输入流上。
常用方法
缓冲流的读取方法功能与InputStream上一致,需要知道的时read方法调用后缓冲流会一次性读取缓冲区大小的字节数据并存入缓冲区,然后再根据我们调用read方法读取的字节数进行返回,直到缓冲区所有数据都已经通过read方法返回后会再次读取一组数据进缓冲区。即:块读取操作

对象流

对象流是一对高级流,在流链接中的作用是完成对象的序列化反序列化

序列化:是对象输出流的工作,将一个对象按照其结构转换为一组字节的过程。

反序列化:是对象输入流的工作,将一组字节还原为对象的过程。

java.io.ObjectInputStream对象输入流,继承自java.io.InputStream

常用构造器

ObjectInputStream(InputStream in):创建一个对象输入流并连接到参数in这个输入流上。

常用方法

Object readObject():进行对象反序列化,将读取的字节转换为一个对象并以Object形式返回(多态)。

如果读取的字节表示的不是一个java对象会抛出异常:java.io.ClassNotFoundException

java.io.ObjectOutputStream对象输出流,继承自java.io.OutputStream

常用构造器

ObjectOutputStream(OutputStream out):创建一个对象输出流并连接到参数out这个输出流上

常用方法

void writeObject(Object obj):进行对象的序列化,将一个java对象序列化成一组字节后再通过连接的输出流将这组字节写出。

如果序列化的对象没有实现可序列化接口:java.io.Serializable就会抛出异常:java.io.NotSerializableException

序列化接口java.io.Serrializable

该接口没有任何抽象方法,但是只有实现了该接口的类的实例才能进行序列化与反序列化。

实现了序列化接口的类建议显示的定义常量:static final long serialVersionUID = 1L;

可以为属性添加关键字transient,被该关键字修饰的属性在序列化是会被忽略,达到对象序列化瘦身的目的。

字符流

java将流按照读写单位划分为字节与字符流。字节流以字节为单位读写,字符流以字符为单位读写。

转换流java.io.InputStreamReader和OutputStreamWriter

功能无需掌握,了解其核心意义:

1:衔接其它字节与字符流

2:将字符与字节进行转换

相当于是现实中的"转换器"

缓冲字符输出流

缓冲字符输出流需要记住的是PrintWriter和BufferedReader

作用:

1:块写或块读文本数据加速

2:可以按行写或读字符串

java.io.PrintWriter 具有自动行刷新的缓冲字符输出流

常用构造器

PrintWriter(String filename) :可以直接对给定路径的文件进行写操作

PrintWriter(File file):可以直接对File表示的文件进行写操作

上述两种构造器内部会自动完成流连接操作。

PrintWriter(OutputStream out):将PW链接在给定的字节流上(构造方法内部会自行完成转换流等流连接)

PrintWriter(Writer writer):将PW链接在其它字符流上

PrintWriter(OutputStream out,boolean autoflush)

PrintWriter(Writer writer,boolean autoflush)

上述两个构造器可以在链接到流上的同时传入第二个参数,如果该值为true则开启了自动行刷新功能。

常用方法

void println(String line):按行写出一行字符串

特点

自动行刷新,当打开了该功能后,每当使用println方法写出一行字符串后就会自动flush一次

java异常处理机制:

  • 异常处理机制是用来处理那些可能存在的异常,但是无法通过修改逻辑完全规避的场景。
  • 而如果通过修改逻辑可以规避的异常是bug,不应当用异常处理机制在运行期间解决!应当在编码时及时修正

try语句块用来包含可能出错的代码片段

catch用来捕获并处理对应的异常,可以定义多个,也可以合并多个异常在一个catch中。

相关文章:

Java阶段一Day19

Java阶段一Day19 文章目录Java阶段一Day19对象流字符流WriterReader转换流缓冲字符流BufferedWriter与PrintWriterBufferedReader异常Throwable、Error、Exception异常处理机制throwthrowstry-catchfinally面试题教师总结新单词JAVA IO对象流对象输入流构造器方法例transient关…...

radmin远程控制软件怎么样,有没有替代品

Radmin 是流行的、屡获殊荣的安全远程控制软件,它使您能够在远程计算机上实时工作,就像使用它自己的键盘和鼠标一样。 您可以从多个地方远程访问同一台计算机,是网络和管理类别中流行的远程桌面工具。 Radmin 是外国软件,在国内使…...

Java反射面试总结(一)

什么是反射? Java的反射是指在程序运行时,对于任意一个类,都可以获取到这个类的所有属性和方法,并能够对其进行操作。通过反射机制,可以在程序运行时动态地创建对象、调用方法、获取属性值等。反射可以帮助我们更轻松…...

【论文阅读】3D-LaneNet

【论文阅读】3D-LaneNet 主要要做的事情就是 lane detection。这里提一下 BEV(Bird‘s Eye View) 感知算法,为了将 2D 图像映射到 3D 空间中,能够更准确的检测物体位置,需要 BEV 感知的结果。后续还会继续了解这方面内…...

Kafka的概念|架构|搭建|查看命令

Kafka的概念|架构|搭建|查看命令一 Kafka 概述二 使用消息队列的好处三Kafka 定义3.1Kafka 简介3.2Kafka 的特性3.3 Kafka 系统架构3.4 Partation 数据路由规则四 kafka的架构五 搭建kafka5.1环境准备5.2安装kafka5.3 修改配置文件5.4 编辑其他二台虚拟机的配置文件5.5 编辑三台…...

大数据项目实战之数据仓库:电商数据仓库系统——第5章 数据仓库设计

第5章 数据仓库设计 5.1 数据仓库分层规划 优秀可靠的数仓体系,需要良好的数据分层结构。合理的分层,能够使数据体系更加清晰,使复杂问题得以简化。以下是该项目的分层规划。 5.2 数据仓库构建流程 以下是构建数据仓库的完整流程。 5.2.1 …...

OpenHarmony社区运营报告(2023年3月)

目录 本月快讯 一、代码贡献 二、生态进展 三、社区治理 五、社区活动 六、社区及官网运营 本月快讯 • 《OpenHarmony 2022年度运营报告》于3月正式发布,2022年OpenAtom OpenHarmony(以下简称“OpenHarmony”)开源项目潜心务实、深耕发展&am…...

杰林码图像增强算法——超分辨率、图像放大、轮廓和色彩强化算法(二)

一、前言 2023-03-23我发布了基于加权概率模型(杰林码的理论模型)的图像颜色增强和轮廓预测的应用方法。效果还不太明显,于是我又花了2周的时间进行了技术优化。下面仅提供了x86下的BMP和JPG对应的lib和dll,本文中的算法属于我国…...

在three.js中废置对象

基于three.js子如何废置对象(How to dispose of objects) 前言: 为了提高性能,并避免应用程序中的内存泄露,一个重要的方面是废置未使用的类库实体。 每当创建一个three.js中的实例时,都会分配一定数量的内存。然而,three.js会创建在渲染中所必需的特定对象, 例如几何…...

Java中的String类真的不可变吗?

其实在Java中,String类被final修饰,主要是为了保证字符串的不可变性,进而保证了它的安全性。那么final到底是怎么保证字符串安全性的呢?接下来就让我们一起来看看吧。 一. final的作用 1. final关键词修饰的类不可以被其他类继…...

电脑重装了系统开不了机怎么办?

我们的电脑办公用久后也会出现故障问题,例如卡顿反应慢等等,这时候就要进行重装系统了,但是很多小伙伴重装系统后会出现开不了机的问题,其实我们比较常见的也就是电脑重装系统开不了机的情况。有很多小伙伴反映自己不知道应该怎么…...

SPOJ-NSUBSTR - Substrings(SAM求所有长度子串的最大出现次数)

NSUBSTR - Substrings 题面翻译 你得到了一个最多由 250000250000250000 个小写拉丁字母组成的字符串 SSS。定义 F(x)F(x)F(x) 为 SSS 的某些长度为 xxx 的子串在 SSS 中的最大出现次数。即 F(x)max{times(T)}F(x)max\{times(T)\}F(x)max{times(T)},满足 TTT 是 S…...

Mariadb10.5基于同服务器多实例主从配置

本次部署环境:Centos8stream 本次部署mariadb版本: mariadb:10.5 本次部署方式:rpm包直接安装,并通过systemd直接托管 可以参考 /usr/lib/systemd/system/mariadb.service 该文件 # Multi instance version of mariadb. For i…...

linux 修改主机名称

1、hostname命令进行临时更改 如果只需要临时更改主机名&#xff0c;可以使用hostname命令&#xff1a; sudo hostname <new-hostname> 例如&#xff1a; 只需重新打开session终端&#xff0c;就能生效&#xff0c; 但是&#xff0c;重启计算机后会回到旧的主机名。…...

学校的地下网站(学校的地下网站1080P高清)

这个问题本身就提得有问题&#xff0c;为什么这么说&#xff0c;这是因为YouTube本身就不是一个视频网站或者说YouTube不是一个传统的视频网站&#xff01;&#xff01;&#xff01; YouTube能够一家独大&#xff0c;可不仅仅是因为有了Google 这个亲爹&#xff0c;还有一点&am…...

勒索病毒是什么?如何防勒索病毒

勒索病毒并不是某一个病毒&#xff0c;而是一类病毒的统称&#xff0c;主要以邮件、程序、木马、网页挂马的形式进行传播&#xff0c;利用各种加密算法对文件进行加密&#xff0c;被感染者一般无法解密&#xff0c;必须拿到解密的私钥才有可能破解。 已知最早的勒索软件出现于 …...

SpringBoot+VUE+Axios 【链接超时】 后端正常返回结果,前端却出现错误无法接收数据

一、错误原因及解决思路 错误提示表明前端发送的请求在默认的 2500ms 超时时间内没有得到服务器的响应&#xff0c;导致请求失败。尝试以下方法来解决这个问题&#xff1a; 增加请求超时时间&#xff1a;可以通过配置 Axios 请求对象的 timeout 属性来增加请求的超时时间&…...

【状态估计】基于增强数值稳定性的无迹卡尔曼滤波多机电力系统动态状态估计(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

快速排序的简单理解

详细描述 快速排序通过一趟排序将待排序列分割成独立的两部分&#xff0c;其中一部分序列的关键字均比另一部分序列的关键字小&#xff0c;则可分别对这两部分序列继续进行排序&#xff0c;以达到整个序列有序的目的。 快速排序详细的执行步骤如下&#xff1a; 从序列中挑出…...

短视频多平台发布软件功能详解

随着移动互联网的普及和短视频的兴起&#xff0c;短视频发布软件越来越受到人们的关注。短视频发布软件除了常规的短视频发布功能&#xff0c;还拥有智能创作、帐号绑定、短视频一键发布、视频任务管理和数据统计等一系列实用功能。下面我们将分步骤详细介绍一下这些功能。   …...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

Python Einops库:深度学习中的张量操作革命

Einops&#xff08;爱因斯坦操作库&#xff09;就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库&#xff0c;用类似自然语言的表达式替代了晦涩的API调用&#xff0c;彻底改变了深度学习工程…...

API网关Kong的鉴权与限流:高并发场景下的核心实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中&#xff0c;API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关&#xff0c;Kong凭借其插件化架构…...