Java基础 - 10 - File、IO流(一)

File:代表文本

IO流:读写数据 

 一. File

  File是java.io.包下的类,File类的对象,用于代表当前操作系统的文件(可以是文件或文件夹

  注意:File类只能对文件本身进行操作,不能读写文件里面存储的数据

1.1 创建File类的对象

构造器说明
public File(String pathname)根据文件路径创建文件对象
public File(String parent, String child)根据父路径和子路径名字创建文件对象
public File(File parent, String child)根据父路径对应文件对象和子路径名字创建文件对象

注意

        · File对象既可以代表文件,也可以代表文件夹

        · File封装的对象仅仅是一个路径名,这个路径可以是存在的,也允许是不存在的

绝对路径、相对路径

        绝对路径:从盘符开始

        相对路径:不带盘符,默认直接到当前工程下的目录寻找文件

public class demo {public static void main(String[] args) {//文件路径名://路径分隔符: 三种写法File f1 = new File("D:/zm/1.txt"); //指代某个具体的文件//File f1 = new File("D:\\zm\\1.txt");//File f1 = new File("D:"+File.separator+"zm"+File.separator+"1.txt");System.out.println(f1.length()); //文件大小File f2 = new File("D:/zm"); //指代某个文件夹System.out.println(f2.length());File f3 = new File("D:/zm/2.txt"); //指代某个不存在的文件System.out.println(f3.length()); //0System.out.println(f3.exists()); //false 不存在//绝对路径:带盘符的//File f4 = new File("D:\\code\\IJProject\\demo\\src\\wosun.txt");//相对路径:不带盘符,默认是直接去工程下寻找文件File f4 = new File("demo\\src\\wosun.txt");System.out.println(f4.length());}
}

1.2 常用方法:判断文件类型、获取文件信息

方法名称说明
public boolean exists()判断当前文件对象,对应的文件路径是否存在,存在返回true
public boolean isFile()判断当前文件对象指代的是否是文件,是文件返回true,反之false
public boolean isDirectory()判断当前文件对象指代的是否是文件夹,是文件夹返回true,反之false
public String getName()获取文件的名称(包含后缀)
public long length()获取文件的大小,返回字节个数
public long lastModified()获取文件的最后修改时间

public String getPath()

获取创建文件对象时,使用的路径
public String getAbsolutePath()获取绝对路径
public class demo {public static void main(String[] args) {//创建文件对象,指代某个文件File f1 = new File("D:/zm/1.txt");//创建文件对象,指代某个文件夹(不存在的)File f2 = new File("D:/wosun");//1.public boolean exists() 判断当前文件对象,对应的文件路径是否存在,存在返回trueSystem.out.println(f1.exists()); //trueSystem.out.println(f2.exists()); //false//2.public boolean isFile() 判断当前文件对象指代的是否是文件,是文件返回true,反之falseSystem.out.println(f1.isFile()); //true//3.public boolean isDirectory() 判断当前文件对象指代的是否是文件夹,是文件夹返回true,反之falseSystem.out.println(f1.isDirectory()); //false//4.public String getName() 获取文件的名称(包含后缀)System.out.println(f1.getName()); //1.txt//5.public long length() 获取文件的大小,返回字节个数System.out.println(f1.length());//6.public long lastModified() 获取文件的最后修改时间System.out.println(f1.lastModified());SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println(sdf.format(f1.lastModified()));//7.public String getPath() 获取创建文件对象时,使用的路径System.out.println(f1.getPath()); //创建的时候是绝对路径就是绝对路径File f3 = new File("src\\wosun.txt"); //创建的时候是相对路径就是相对路径System.out.println(f3.getPath());//8.public String getAbsolutePath() 获取绝对路径System.out.println(f3.getAbsolutePath());}
}

1.3 常用方法:创建文件、删除文件

方法名称说明
public boolean createNewFile()创建一个新文件(文件内容为空),创建成功返回true,反之false
public boolean mkdir()用于创建文件夹,注意:只能创建一级文件夹
public boolean mkdirs()用于创建文件夹,注意:可以创建多级文件夹
public boolean delete()删除文件或空文件夹,注意:不能删除非空文件夹

注意:delete方法默认只能删除文件和空文件夹,删除后的文件不会进入回收站

public class demo {public static void main(String[] args) throws IOException {File f1 = new File("D:/zm/2.txt"); // 不存在的文件File f2 = new File("D:/zm/bbb/ccc/ddd"); //三级文件夹File f3 = new File("D:/zm/aaa"); //一级文件夹//1.public boolean createNewFile() 创建一个新文件(文件内容为空),创建成功返回true,反之falseSystem.out.println(f1.createNewFile()); //不存在则创建成功,存在则创建失败//2.public boolean mkdir() 用于创建文件夹,注意:只能创建一级文件夹System.out.println(f2.mkdir()); //falseSystem.out.println(f3.mkdir()); //true//3.public boolean mkdirs() 用于创建文件夹,注意:可以创建多级文件夹System.out.println(f2.mkdirs()); //true//4.public boolean delete() 删除文件或空文件夹,注意:不能删除非空文件夹System.out.println(f1.delete());System.out.println(f3.delete());System.out.println(f2.delete()); //删除"D:/zm/bbb/ccc/ddd"中的最后的空文件夹ddd}
}

1.4 常见方法:遍历文件夹

方法名称说明
public String[] list()获取当前目录下所有的“一级文件名称”到一个字符串数组中去返回
public File[] listFiles()获取当前目录下所有的“一级文件对象”到一个文件对象数组中去返回

使用listFiles方法时的注意事项:

· 当主调是文件,或者路径不存在时,返回null

· 当主调是空文件夹,返回一个长度为0的数组

· 当主调是一个有内容的文件夹时,将里面所有一级文件和文件夹的路径放在File数组中返回

· 当主调是一个文件夹,且里面有隐藏文件时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏文件

· 当主调是一个文件夹,但是没有权限访问该文件夹时,返回null

public class demo {public static void main(String[] args) throws IOException {File f1 = new File("D:/zm");//1.public String[] list() 获取当前目录下所有的“一级文件名称”到一个字符串数组中去返回String[] nameList = f1.list();for (String s : nameList) {System.out.println(s); //文件名称 eg:1.txt}//2.public File[] listFiles() 获取当前目录下所有的“一级文件对象”到一个文件对象数组中去返回//使用listFiles方法时的注意事项://· 当主调是一个有内容的文件夹时,将里面所有一级文件和文件夹的路径放在File数组中返回File[] files1 = f1.listFiles();for (File file : files1) {System.out.println(file); //文件对象 eg:D:\zm\1.txt}//· 当主调是文件,或者路径不存在时,返回nullFile f2 = new File("D:/zm/1.txt"); //主调是文件File[] files2 = f2.listFiles();System.out.println(files2); //nullFile f3 = new File("D:/recourse"); //路径不存在File[] files3 = f3.listFiles();System.out.println(files3); //null//· 当主调是空文件夹,返回一个长度为0的数组File f4 = new File("D:/zm/bbb"); //主调是空文件夹File[] files4 = f4.listFiles();System.out.println(Arrays.toString(files4)); //[]//· 当主调是一个文件夹,且里面有隐藏文件时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏文件//· 当主调是一个文件夹,但是没有权限访问该文件夹时,返回null}
}

二. 方法递归

        · 递归是一种算法,在程序设计语言中广泛使用

        · 从形式上说:方法调用自身的形式称为方法递归(recursion)

递归的形式

        · 直接递归:方法自己调用自己

        · 间接递归:方法调用其他方法,其他方法又回调方法自己

使用方法递归时需要注意的问题:

        · 递归如果没有控制好终止,会出现递归死循环,导致栈内存溢出错误

public class demo {public static void main(String[] args) {test1();  //java.lang.StackOverflowError 栈内存溢出错误}//直接方法递归public static void test1(){System.out.println("===test1===");test1();}//间接方法递归public static void test2(){System.out.println("===test2===");test3();}public static void test3(){test2();}
}

2.1 递归算法三要素

        · 递归的公式:f(n)=f(n-1)*n

        · 递归的终结点:f(1)

        · 递归的方向必须走向终结点

2.2 递归算法案例

2.2.1 案例:n的阶乘

public class demo {public static void main(String[] args) {System.out.println("6的阶乘:"+f(6));}public static int f(int n){//终结点if(n==1){return 1;}else{return f(n-1)*n;}}
}

2.2.2 案例:1-n的和

public class demo {public static void main(String[] args) {System.out.println("1-100的和:"+f(100));}public static int f(int n){//终结点if(n==1){return 1;}else{return f(n-1)+n;}}
}

2.2.3 猴子吃桃问题

public class demo {public static void main(String[] args) {// 猴子吃桃问题// f(10)=1// f(x)表示f(x+1)的前一天// f(x) = 2 * (f(x+1) + 1)// 求 f(1)System.out.println("猴子第一天摘的桃子个数:" + f(1));}public static int f(int n){//终结点if(n==10){return 1;}else{return 2 * (f(n+1) + 1);}}
}

2.2.4 啤酒问题

问题:啤酒2元一瓶,4个盖子可以换一瓶,2个瓶子可以换一瓶,10块钱可以喝到几瓶?

public class demo {public static int totalNum = 0;  //酒的总共数量public static int lastBottleNum = 0; //剩余的瓶子数public static int lastCoverNum = 0; //剩余的瓶盖数public static void main(String[] args) {//问题:啤酒2元一瓶,4个盖子可以换一瓶,2个瓶子可以换一瓶,10块钱可以喝到几瓶?buy(10);System.out.println("购买的酒的数量:"+totalNum);System.out.println("剩余瓶盖数:"+lastCoverNum);System.out.println("剩余瓶子数:"+lastBottleNum);}private static void buy(int money) {//买酒的数量int buyNum = money / 2;totalNum += buyNum;//当前剩余的瓶子数和瓶盖数lastBottleNum += buyNum;lastCoverNum += buyNum;int allMoney = 0; //可以换的钱数(4个盖子可值2元,2个瓶子可值2元)if(lastCoverNum >= 4){allMoney += (lastCoverNum/4)*2;}lastCoverNum = lastCoverNum % 4;if(lastBottleNum >= 2){allMoney += (lastBottleNum/2)*2;}lastBottleNum = lastBottleNum % 2;if(allMoney>=2){buy(allMoney);}}
}

2.3 递归与File

2.3.1 案例:文件搜索

public class demo {public static void main(String[] args) throws IOException {File dir = new File("D:/"); //要搜索的路径(目录)String fileName = "QQ.exe"; //要搜索的文件名searchFile(dir,fileName);}/*** 去目录下搜索某个文件* @param dir 目录* @param fileName 要搜索的文件名*/public static void searchFile(File dir,String fileName) throws IOException {//拦截非法情况(路径为null,路径不存在)if(dir == null || !dir.exists()){return; //无法搜索}//指定路径是一个文件if(dir.isFile()){//判断该文件名是否是搜索的文件名if(dir.getName().equals(fileName)){//是,打印路径System.out.println(dir.getAbsolutePath());return; //跳出方法}else{return; //搜索失败}}//指定路径dir不是null,且存在,且是一个文件夹(目录)//获取当前目录下的全部一级文件对象File[] files = dir.listFiles();//判断当前目录下是否存在一级文件对象,是否可以拿到一级文件对象if(files != null && files.length > 0){//遍历全部一级文件对象for (File file : files) {//判断文件是文件还是文件夹if(file.isFile()){//是文件if(file.getName().equals(fileName)){System.out.println(file.getAbsolutePath());//启动该程序Runtime runtime = Runtime.getRuntime();runtime.exec(file.getAbsolutePath());return; //结束方法}}else if(file.isDirectory()){//是文件夹  重复该过程searchFile(file,fileName);}}}}
}

2.3.2 案例:删除文件夹

public class demo {public static void main(String[] args) throws IOException {File dir = new File("D:/桌面/aaa");//System.out.println(dir.delete());  //false 非空文件夹不能通过delete()方法删除deleteDir(dir);}//删除非空文件夹public static void deleteDir(File dir){//指定路径为null或不存在if(dir == null || !dir.exists()){System.out.println("删除失败,指定路径为null或不存在");return;}//指定路径是文件,直接删除if(dir.isFile()){dir.delete();return;}//dir存在且是文件夹//判断dir是否为空文件夹//提取dir目录下的一级文件对象File[] files = dir.listFiles();//files为null,没有删除权限if(files == null){System.out.println("没有删除权限");return;}//因为删除内容后依旧要删除自己,所以这一段代码可以省略
//        //files.length为0,说明dir是空文件夹
//        if(files.length == 0){
//            dir.delete();
//            return;
//        }//dir是一个有内容的文件夹(先删除里里面的内容再删除自己)//先删除里里面的内容for (File file : files) {if(file.isFile()){file.delete();}else{deleteDir(file);}}//再删除自己dir.delete();}
}

三. 字符集

3.1 标准ASCII字符集

· ASCII(American Standard Code for Information Interchange):美国信息交换标准代码,包括了英文、数字、符号等

· 标准ASCII使用1个字节存储一个字符,首尾是0,总共可表示128个字符

3.2 GBK(汉字内码扩展规范,国标)

· 汉字编码字符集,包含了2万多个汉字等字符,GBK中一个中文字符编码成两个字节的形式存储

· 注意:GBK兼容了ASCII字符集(英文、数字占1个字节)

· GBK规定:汉字的第一个字节的第一位必须是1

3.3 Unicode字符集(统一码,也叫万国码)

· Unicode是国际组织指定的,可以容纳世界上所有文字、符号的字符集

· UTF-32用4个字节表示一个字符(占存储空间,效率变低)

· UTF-8是Unicode字符集的一种编码方案,采用可变长编码方案,共分四个长度区:1个字节、2个字节、3个字节、4个字节

· UTF-8中英文字符、数字等只占1个字节(兼容标准ASCII编码),汉字字符占用3个字节

注意:

· 字符编码时使用的字符集,和解码时使用的字符集必须一致,否则会出现乱码

· 英文、数字一般不会乱码,因为很多字符集都兼容了ASCII编码

3.4 字符集的编码、解码

        编码:把字符按照指定字符集编码成字节

        解码:把字节按照指定字符集解码成字符

Java代码完成对字符的编码

String提供了如下方法说明
byte[] getBytes()使用平台的默认字符集将该String编码为一系列字节,将结果存储到新的字节数组中
byte[] getBytes(String charsetName)使用指定的字符集将该String编码为一系列字节,将结果存储到新的字节数组中

Java代码完成对字符的解码

String提供了如下方法说明
String(byte[] bytes)通过使用平台的默认字符集解码指定的字节数组来构造新的String
String(byte[] bytes, String charsetName)通过指定的字符集解码指定的字节数组来构造新的String
public class demo {public static void main(String[] args) throws UnsupportedEncodingException {//编码String data = "a我b";byte[] bytes = data.getBytes(); //默认按照平台字符集(UTF-8)进行编码的System.out.println(Arrays.toString(bytes));//按照指定字符集编码byte[] bytes1 = data.getBytes("GBK");System.out.println(Arrays.toString(bytes1));//解码String s1 = new String(bytes); //默认按照平台字符集(UTF-8)进行解码System.out.println(s1); //a我bString s2 = new String(bytes1); //默认按照平台字符集(UTF-8)进行解码System.out.println(s2); //a��b 因为bytes1按照GBK解码,所以按照UTF-8解码会出现乱码String s3 = new String(bytes1,"GBK"); //指定字符集解码System.out.println(s3); //a我b}
}

四. IO流

IO流:输入输出流,用于读写数据

        I指Input,称为输入流:负责把数据读到内存中去

        O指Output,称为输出流:负责写数据出去

IO流的应用场景

IO流的分类

        IO流总体来看就有四大流:字节输入流、字节输出流、字符输入流、字符输出流

4.1 FileInputStream(文件字节输入流)

· 作用:以内存为基准,可以把磁盘文件中的数据以字节的形式读入到内存中去

构造器说明
public FileInputStream(File file)创建字节输入流管道与源文件接通
public FileInputStream(String pathname)创建字节输入流管道与源文件接通
方法名称说明
public int read()每次读取一个字节返回,如果发现没有数据可读会返回-1
public int read(byte[] buffer)每次用一个字节数组去读取数据,返回字节数组读取了多少个字节,如果发现没有数据可读会返回-1

4.1.1 每次读取一个字节read()

· 使用FileInputStream的read()每次读取一个字节,读取性能较差,并且读取汉字输出会乱码

public class demo {public static void main(String[] args) throws Exception {//创建文件字节输入流管道,与源文件接通//public FileInputStream(File file) 创建字节输入流管道与源文件接通InputStream is = new FileInputStream(new File("demo/src/wosun.txt")); //多态//简化写法:推荐使用//public FileInputStream(String pathname) 创建字节输入流管道与源文件接通InputStream fis = new FileInputStream("demo\\src\\wosun.txt"); //多态//开始读取文件的字节数据//public int read()	每次读取一个字节返回,如果发现没有数据可读会返回-1
//        int b1 = fis.read();
//        System.out.println((char) b1); //读第一个字节
//
//        int b2 = fis.read();
//        System.out.println((char) b2); //读第二个字节
//
//        int b3 = fis.read();
//        System.out.println(b3); //如果发现没有数据可读会返回-1//使用循环改造上述代码int b; //用于记住读取的字节while((b = fis.read()) != -1){System.out.print((char) b);}//上述方法一次只读一个字节,读取数据的性能很差(频繁调用系统资源)//上述方法一次只读一个字节,会导致读取汉字输入会乱码!无法避免!//流使用完毕之后,必须关闭!释放系统资源!fis.close();}
}

4.1.2 每次读取多个字节read(byte[] buffer) 

· 使用FileInputStream的read(byte[] buffer)每次读取多个字节,读取性能得到提升,但读取汉字输出还是会乱码

public class demo {public static void main(String[] args) throws Exception {//创建一个字节输入流对象代表字节输入流管道与源文件接通InputStream fis = new FileInputStream("demo\\src\\wosun.txt"); //多态//开始读取文件的字节数据,每次读取多个字节// public int read(byte[] buffer)// 每次读取多个字节,用一个字节数组去读取数据,返回字节数组读取了多少个字节,如果发现没有数据可读会返回-1//byte[] buffer = new byte[1024];  //每次可以读1024个字节,即1KB
//        byte[] buffer = new byte[3];
//        int len1 = fis.read(buffer);  //每次最多读3个字节
//        String s1 = new String(buffer); //解码
//        System.out.println(s1);
//        System.out.println("当次读取的字节数:"+len1);
//
//        //buffer = [abc]
//        //buffer = [66c] //c没有覆盖,因此需要读取多少倒出多少
//        int len2 = fis.read(buffer);
//        //String s2 = new String(buffer);  //66c
//        String s2 = new String(buffer,0,len2); //66
//        System.out.println(s2);
//        System.out.println("当次读取的字节数:"+len2);
//
//        int len3 = fis.read(buffer);
//        System.out.println("当次读取的字节数:"+len3); //没有字节后读取的字节长度会是-1//优化byte[] buffer = new byte[3];int len; //记录每次读取了多少个字节while((len = fis.read(buffer)) != -1){String s = new String(buffer,0,len);System.out.println("当前读取到的字节:"+s+" 当前读取到的字节数:"+len);}fis.close();}
}

4.1.3 一次读取完全部字节

        可以解决字节流读取中文输出乱码的问题,但是如果文件过大,创建的字节数组也会过大,可能引起内存溢出

一次读取完全部字节的两种方式

· 方式一:自己定义一个字节数组与被读取的文件大小一样大,然后使用该字节数组,一次读完文件的全部字节

· 方式二:Java官方为InputStream提供了如下方法,可以直接把文件的全部字节读取到一个字节数组中返回

public class demo {public static void main(String[] args) throws Exception {//创建一个文件对象File f = new File("demo\\src\\wosun.txt");//创建一个字节输入流对象代表字节输入流管道与源文件接通InputStream fis = new FileInputStream(f); //多态//方式1:自己定义一个字节数组与被读取的文件大小一样大,然后使用该字节数组,一次读完文件的全部字节
//        //length:文件大小
//        long length = f.length();
//        //该方案只适合读相对来说较小的文件(不超过内存容量)
//        byte[] buffer = new byte[(int) length];
//
//        int len = fis.read(buffer); //len:当前读取到的字节数
//        String s = new String(buffer,0,len);
//        System.out.println("当前读取到的字节:"+s+" 当前读取到的字节数:"+len);//方式2:Java官方为InputStream提供了read方法,可以直接把文件的全部字节读取到一个字节数组中返回byte[] buffer = fis.readAllBytes(); //在jdk9中才出现的System.out.println(new String(buffer));fis.close();}
}

注意:

        读写文本内容更适合用字符流;字节流适合做数据的转移,如文件复制等

4.2 FileOutputStream(文件字节输出流)

· 作用:以内存为基准,把内存中的数据以字节的形式写出到文件中去

构造器说明
public FileOutputStream(File file)创建字节输出流管道与源文件对象接通
public FileOutputStream(String filepath)创建字节输出流管道与源文件路径接通
public FileOutputStream(File file, boolean append)创建字节输出流管道与源文件对象接通,可追加数据
public FileOutputStream(String filepath, boolean append)创建字节输出流管道与源文件路径接通,可追加数据
方法名称说明
public void write(int a)写一个字节出去
public int write(byte[] buffer)写一个字节数组出去
public int write(byte[] buffer, int pos, int len)写一个字节数组的一部分出去
public void close() throws IOException关闭流
public class demo {public static void main(String[] args) throws Exception {//相对路径//以“./”开头,代表当前目录和文件目录在同一个目录里,“./”也可以省略不写!//以"../"开头:向上走一级,代表目标文件在当前文件所在的上一级目录;//以"../../"开头:向上走两级,代表父级的父级目录,也就是上上级目录,再说明白点,就是上一级目录的上一级目录//以"/”开头,代表根目录//创建一个字节输出流管道与目标文件接通//覆盖管道,会覆盖文件中原有的数据//OutputStream os = new FileOutputStream("demo/src/wosun.txt");//追加管道,不会覆盖文件中原有的数据OutputStream os = new FileOutputStream("demo/src/wosun.txt",true);//开始写字节数据出去//每次写一个字节os.write(97);  //97就是一个字节,代表aos.write('b'); //'b'也是一个字节//os.write('你'); //乱码,因为write(int a)默认写一个字节,你在系统默认字符集(UTF-8)中占3个字节,因此乱码byte[] bytes = "abc你好星期天abc".getBytes();os.write(bytes);//换行os.write("\r\n".getBytes());os.write(bytes,3,15); //从3开始,写入15个字节,正好是“你好星期六”os.close(); //关闭流}
}

4.3 字节流案例:文件复制

        字节流非常适合做一切文件的复制操作(任何文件的底层都是字节,字节流做副职,是一字不漏的转移完全部字节,只要复制后的文件格式一致就没有问题)

public class demo {public static void main(String[] args) throws Exception {//文件复制//需要创建一个字节输入流管道与原文件接通InputStream is = new FileInputStream("D:/zm/1.jpg");//创建一个字节输出流管道与目标位置接通OutputStream os = new FileOutputStream("D:/zm/aaa/1.jpg"); //要自己填写文件名//创建一个字节数组,负责转移字节数据byte[] buffer = new byte[1024];  //一次可以读取1KB//从字节输入流中读取字节数据,然后写到字节输出流中,读多少写多少//每次读取多个字节read(byte[] buffer)int len; //用来记录每次读取了多少字节while((len = is.read(buffer)) != -1){os.write(buffer,0,len);}//后创建的流先关闭,先创建的流后关闭os.close();is.close();System.out.println("复制完成");}
}//用try-catch-finally改良后的文件复制
public class demo {public static void main(String[] args) {InputStream is = null;OutputStream os = null;try {System.out.println(10/0); //出现异常//文件复制//需要创建一个字节输入流管道与原文件接通is = new FileInputStream("D:/zm/1.jpg");//创建一个字节输出流管道与目标位置接通os = new FileOutputStream("D:/zm/aaa/1.jpg"); //要自己填写文件名System.out.println(10/0); //出现异常//创建一个字节数组,负责转移字节数据byte[] buffer = new byte[1024];  //一次可以读取1KB//从字节输入流中读取字节数据,然后写到字节输出流中,读多少写多少//每次读取多个字节read(byte[] buffer)int len; //用来记录每次读取了多少字节while((len = is.read(buffer)) != -1){os.write(buffer,0,len);}System.out.println("复制完成");} catch (IOException e) {e.printStackTrace();} finally {//释放资源的操作try {if(os != null){os.close();}} catch (IOException e) {e.printStackTrace();}try {if(is != null){is.close();}} catch (IOException e) {e.printStackTrace();}}}
}

4.4 释放资源的方式

4.4.1 try-catch-finally

public class demo {public static void main(String[] args) throws Exception {try{System.out.println(10/2); //没有异常,也会执行finally中的代码// System.out.println(10/0); //出现异常,也会执行finally中的代码// return; //跳出方法的执行,也会执行finally中的代码// System.exit(0); //虚拟机jvm挂掉,就不会执行finally中的代码}catch (Exception e){e.printStackTrace();}finally {System.out.println("======finally执行了一次======");}System.out.println(chu(10, 2)); //111}public static int chu(int a,int b){try{return a/b;}catch (Exception e){e.printStackTrace();return -1;}finally {//千万不要在finally里返回数据return 111;}}
}

4.4.2 try-with-resource

public class demo {public static void main(String[] args) {//文件复制try(//需要创建一个字节输入流管道与原文件接通InputStream is = new FileInputStream("D:/zm/1.jpg");//创建一个字节输出流管道与目标位置接通OutputStream os = new FileOutputStream("D:/zm/aaa/1.jpg"); //要自己填写文件名//注意:这里只能放置资源对象(流对象)//什么是资源?// 资源都是会实现AutoCloseable接口,资源都会有一个close方法// 并且资源放到这里(try()里面)后,当它用完之后,会被自动调用其close方法完成资源的释放操作) {//创建一个字节数组,负责转移字节数据byte[] buffer = new byte[1024];  //一次可以读取1KB//从字节输入流中读取字节数据,然后写到字节输出流中,读多少写多少//每次读取多个字节read(byte[] buffer)int len; //用来记录每次读取了多少字节while((len = is.read(buffer)) != -1){os.write(buffer,0,len);}System.out.println("复制完成");} catch (IOException e) {e.printStackTrace();}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/790424.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MyBatis动态SQL--if 标签

mybatis动态sql对我们来说是非常常见的,比如在下面这样一个场景中, 我们需要多条件查询,但是查询的条件又不是固定的,是可以动态改变的,那我们就需要用到动态sql去完成。 动态SQL之 if 标签 接下来我们介绍第一个动态…

Day43 动态规划 part05

Day43 动态规划 part05 1049.最后一块石头的重量II 我的思路: 提示说和划分两个和相等的子集差不多,猛然想到,这道题不就是划分子集,用sum - 和最大*2 代码就是划分和相同的子集的变形 解答: class Solution {public int last…

【JavaScript】函数 ⑥ ( 使用 arguments 获取所有实参 | arguments 内置对象 | 伪数组概念 )

文章目录 一、使用 arguments 获取所有实参1、arguments 内置对象2、伪数组概念3、arguments 实参遍历4、arguments 代码示例 - 基本使用5、arguments 代码示例 - 遍历实参 一、使用 arguments 获取所有实参 1、arguments 内置对象 在 定义 JavaScript 函数 时 , 有时 不确定 形…

使用LangChain编写图检索查询实现RAG

大家好,检索增强生成(Retrieval-Augmented Generation,简称RAG)是一种先进的人工智能技术,通过整合大型语言模型(LLM)的内部知识和外部权威数据源,来提升生成式AI模型的表现。 本文…

安全可靠!麒麟信安操作系统各版本均不受liblzma/xz漏洞影响!

近日,XZ Utils 5.6.0和5.6.1版本存在严重后门风险的消息披露后,麒麟信安立即展开全面排查,经分析验证,麒麟信安操作系统各版本均不受liblzma/xz漏洞影响。 关于liblzma/xz漏洞 漏洞描述 xz 5.6.0 与 5.6.1 版本的上游代码中发现…

ComplexHeatmap绘图:注释、图例、热图基础(自备)

目录 基础介绍 Heatmap绘图基础参数 数据 作图参数 Heatmap Annotations(注释) 基础注释设置 简单注释测试 anno_points散点注释 anno_lines连线注释 anno_barplot条形图 anno_boxplot箱线图 anno_histogram直方图 热图组合 基础组合 进行…

【热门话题】文言一心与ChatGPT-4:一场跨时代智能对话系统的深度比较

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 文言一心与ChatGPT-4:一场跨时代智能对话系统的深度比较一、技术背景…

Maven--lib分离的打包方式

就是把lib包和source源码分开打包。优势就是,面对频繁更新的应用场景时,可以只更新源码包(当然,前提是你的依赖没有增减)。尤其是使用jenkins更新项目时,会省去很多时间吧? 不同项目的 lib之间不…

SQL语句生成器,支持MSSQL/MYSQL/SQLITE/ACCESS/EXCEL

经过7个月的艰苦开发,SQL语句生成器终于和各位见面了,因为工程量浩大,一度做到崩溃,差点烂尾,好在经过N次激烈思想斗争后还是坚持了下来累累累累累累累 本软件能够自动生成SQL语句及对应的易语言代码,还有相…

图片二维码如何制作生成?常规图片格式的二维码制作技巧

图片是展示信息很常用的一种方式,而现在查看图片很多人会通过二维码的形式来展现,这种方式优势在于更加的灵活,能够通过一个二维码展示大量的图片内容。那么图片二维码是如何制作生成的呢? 想要快速的将图片转二维码使用&#xf…

mapbox-gl扩展sprites图片

在mapbox-gl.js中,通过在styles中设置sprite和glyphs,实现样式图标和字体的加载。而一旦style加载完成,如果重置地图中的style,则会导致地图全部重新加载,图层的顺序,地图上的要素,都会丢失&…

智慧城市治理:构建全域覆盖的城市时空感知体系

TSINGSEE青犀AI算法中台是一款平台型产品,专注于提供各行业中小场景部署解决方案。平台具备接入广、性能强、支持跨平台、芯片国产化等特点,可提供丰富的视图接入能力和智能分析能力。 平台采用了多项IT高新技术,包括视频编解码技术、嵌入式…

成都直播基地出租:天府新区兴隆湖天府锋巢直播产业基地

天府新区兴隆湖天府锋巢直播产业基地,作为成都乃至西部地区的一颗璀璨明珠,正以其独特的魅力和无限的潜力,吸引着越来越多的目光。这里不仅是成都直播产业的聚集地,更是传统企业转型升级的摇篮,是新媒体时代下的创新高…

多态--下

文章目录 概念多态如何实现的指向谁调谁?例子分析 含有虚函数类的大小是多少?虚函数地址虚表地址多继承的子类的大小怎么计算?练习题虚函数和虚继承 概念 优先使用组合、而不是继承; 继承会破坏父类的封装、因为子类也可以调用到父类的函数;…

RESTful规范总结

概念:RESTful(Representational State Transfer 的缩写)是一种广泛使用的API架构风格。 1.资源:在REST API的设计中,首先需要面向资源建模,其中每个节点是是一个简单资源或集合资源。 1.1一个集合包含相同…

基于Uni-app的体育场馆预约系统的设计与实现

个人介绍 hello hello~ ,这里是 code袁~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹 🦁作者简介:一名喜欢分享和记录学习的…

如何操作RAID 0阵列的扩容?

正文共:1888 字 23 图,预估阅读时间:2 分钟 RAID(Redundant Array of Independent Disks)即独立磁盘冗余阵列,通常简称为磁盘阵列,在高级磁盘阵列中,部分物理存储空间会用来记录保存…

【性能调优】Java服务端性能优化与实战

一、背景 降本增效:随着公司业务的发展和用户规模的增加,当前服务的QPS已经远远不能满足业务需求,需要申请更多CPU资源,来提升QPS,满足业务发展,但是公司硬件资源有限,额外申请多余资源&#x…

OpenHarmony实战:小型系统器件驱动移植

本章节讲解如何移植各类器件驱动。 LCD驱动移植 移植LCD驱动的主要工作是编写一个驱动,在驱动中生成模型的实例,并完成注册。 这些LCD的驱动被放置在源码目录//drivers/hdf_core/framework/model/display/driver/panel中。 创建Panel驱动 创建HDF驱动…

vulnhub pWnOS v2.0通关

知识点总结: 1.通过模块来寻找漏洞 2.msf查找漏洞 3.通过网站源代码,查看模块信息 环境准备 攻击机:kali2023 靶机:pWnOS v2.0 安装地址:pWnOS: 2.0 (Pre-Release) ~ VulnHub 在安装网址中看到,该靶…