JAVA进阶--File类、递归、字符集、IO流--2022年9月6日
第一节 File类

1、File对象
A、File类的作用
创建对象定位文件,可以删除、获取文件信息等。但是不能读写文件内容。
B、File类构建对象的方式
File file = new File(文件/文件夹/绝对路径/相对路径);

C、绝对路径和相对路径是什么样的?
绝对路径是带盘符的
相对路径是不带盘符的,默认到当前工程下寻找文件。

1 package com.itheima.d1_file; 2 3 import java.io.File; 4 5 /** 6 目标:学会创建File对象定位操作系统的文件(文件 文件夹的) 7 */ 8 public class FileDemo { 9 public static void main(String[] args) { 10 // 1、创建File对象(指定了文件的路径) 11 // 路径写法: D:\resources\xueshan.jpeg 12 // D:/resources/xueshan.jpeg 13 // File.separator 14 // File f = new File("D:\\resources\\xueshan.jpeg"); 15 // File f = new File("D:/resources/xueshan.jpeg"); 16 File f = new File("D:" + File.separator+"resources"+ File.separator +"xueshan.jpeg"); 17 long size = f.length(); // 是文件的字节大小 18 System.out.println(size); 19 20 // 2、File创建对象,支持绝对路径 支持相对路径(重点) 21 File f1 = new File("D:\\resources\\beauty.jpeg"); // 绝对路径 22 System.out.println(f1.length()); 23 24 // 相对路径:一般定位模块中的文件的。 相对到工程下!! 25 File f2 = new File("file-io-app/src/data.txt"); 26 System.out.println(f2.length()); 27 28 // 3、File创建对象 ,可以是文件也可以是文件夹 29 File f3 = new File("D:\\resources"); 30 System.out.println(f3.exists()); // 判断这个路径是否存在,这个文件夹存在否 31 32 } 33 }
\ 叫做反斜杠 一般写路径要在这个前面再加一个反斜杠,告诉java反斜杠就是反斜杠
或者可以直接使用/ 正斜杠
或者可以使用File.separator 用这个好处是,他会随着操作系统的不同,自动切换 比如windows就用反斜杠,linux就用正斜杠
2、File类常用API
A、判断文件类型、获取文件信息功能

1 package com.itheima.d1_file; 2 import java.io.File; 3 import java.text.SimpleDateFormat; 4 5 /** 6 目标:File类的获取功能的API 7 - public String getAbsolutePath() :返回此File的绝对路径名字符串。 8 - public String getPath() : 获取创建文件对象的时候用的路径 9 - public String getName() : 返回由此File表示的文件或目录的名称。 10 - public long length() : 返回由此File表示的文件的长度。 11 */ 12 public class FileDemo02 { 13 public static void main(String[] args) { 14 // 1.绝对路径创建一个文件对象 15 File f1 = new File("D:/resources/xueshan.jpeg"); 16 // a.获取它的绝对路径。 17 System.out.println(f1.getAbsolutePath()); 18 // b.获取文件定义的时候使用的路径。 19 System.out.println(f1.getPath()); 20 // c.获取文件的名称:带后缀。 21 System.out.println(f1.getName()); 22 // d.获取文件的大小:字节个数。 23 System.out.println(f1.length()); // 字节大小 24 // e.获取文件的最后修改时间 25 long time = f1.lastModified(); 26 System.out.println("最后修改时间:" + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(time)); 27 // f、判断文件是文件还是文件夹 28 System.out.println(f1.isFile()); // true 29 System.out.println(f1.isDirectory()); // false 30 31 System.out.println("-------------------------"); 32 33 File f2 = new File("file-io-app\\src\\data.txt"); 34 // a.获取它的绝对路径。 35 System.out.println(f2.getAbsolutePath()); 36 // b.获取文件定义的时候使用的路径。 37 System.out.println(f2.getPath()); 38 // c.获取文件的名称:带后缀。 39 System.out.println(f2.getName()); 40 // d.获取文件的大小:字节个数。 41 System.out.println(f2.length()); // 字节大小 42 // e.获取文件的最后修改时间 43 long time1 = f2.lastModified(); 44 System.out.println("最后修改时间:" + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(time1)); 45 // f、判断文件是文件还是文件夹 46 System.out.println(f2.isFile()); // true 47 System.out.println(f2.isDirectory()); // false 48 System.out.println(f2.exists()); // true 49 50 File file = new File("D:/"); 51 System.out.println(file.isFile()); // false 52 System.out.println(file.isDirectory()); // true 53 System.out.println(file.exists()); // true 54 55 File file1 = new File("D:/aaa"); 56 System.out.println(file1.isFile()); // false 57 System.out.println(file1.isDirectory()); // false 58 System.out.println(file1.exists()); // false 59 60 } 61 }
B、文件的删除和创建功能

1 package com.itheima.d1_file; 2 3 import java.io.File; 4 import java.io.IOException; 5 6 /** 7 目标:File类的创建和删除的方法 8 - public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时, 9 创建一个新的空文件。 (几乎不用的,因为以后文件都是自动创建的!) 10 - public boolean delete() :删除由此File表示的文件或目录。 (只能删除空目录) 11 - public boolean mkdir() :创建由此File表示的目录。(只能创建一级目录) 12 - public boolean mkdirs() :可以创建多级目录(建议使用的) 13 */ 14 public class FileDemo03 { 15 public static void main(String[] args) throws IOException { 16 File f = new File("file-io-app\\src\\data.txt"); 17 // a.创建新文件,创建成功返回true ,反之 ,不需要这个,以后文件写出去的时候都会自动创建 18 System.out.println(f.createNewFile()); 19 File f1 = new File("file-io-app\\src\\data02.txt"); 20 System.out.println(f1.createNewFile()); // (几乎不用的,因为以后文件都是自动创建的!) 21 22 // b.mkdir创建一级目录 23 File f2 = new File("D:/resources/aaa"); 24 System.out.println(f2.mkdir()); 25 26 // c.mkdirs创建多级目录(重点) 27 File f3 = new File("D:/resources/ccc/ddd/eee/ffff"); 28 // System.out.println(f3.mkdir()); 29 System.out.println(f3.mkdirs()); // 支持多级创建 30 31 // d.删除文件或者空文件夹 32 System.out.println(f1.delete()); 33 File f4 = new File("D:/resources/xueshan.jpeg"); 34 System.out.println(f4.delete()); // 占用一样可以删除 35 36 // 只能删除空文件夹,不能删除非空文件夹. 37 File f5 = new File("D:/resources/aaa"); 38 System.out.println(f5.delete()); 39 } 40 }
C、File类的遍历功能

1 package com.itheima.d1_file; 2 3 import java.io.File; 4 import java.util.Arrays; 5 6 /** 7 8 目标:File针对目录的遍历 9 - public String[] list(): 10 获取当前目录下所有的"一级文件名称"到一个字符串数组中去返回。 11 - public File[] listFiles()(常用): 12 获取当前目录下所有的"一级文件对象"到一个文件对象数组中去返回(重点) 13 */ 14 public class FileDemo04 { 15 public static void main(String[] args) { 16 // 1、定位一个目录 17 File f1 = new File("D:/resources"); 18 String[] names = f1.list(); 19 for (String name : names) { 20 System.out.println(name); 21 } 22 23 // 2.一级文件对象 24 // 获取当前目录下所有的"一级文件对象"到一个文件对象数组中去返回(重点) 25 File[] files = f1.listFiles(); 26 for (File f : files) { 27 System.out.println(f.getAbsolutePath()); 28 } 29 30 // 注意事项 31 File dir = new File("D:/resources/ddd"); 32 File[] files1 = dir.listFiles(); 33 System.out.println(Arrays.toString(files1)); 34 } 35 }
第二节 方法递归
1、什么是递归
方法调用自己的形式称为方法递归
2、什么是递归死循环
方法无限调用自己,无法终止,最终引起栈内存溢出

1 package com.itheima.d2_recusion; 2 3 /** 4 递归的形式 5 */ 6 public class RecursionDemo01 { 7 public static void main(String[] args) { 8 test2(); 9 } 10 11 public static void test(){ 12 System.out.println("=======test被执行========"); 13 test(); // 方法递归 直接递归形式 14 } 15 16 public static void test2(){ 17 System.out.println("=======test2被执行========"); 18 test3(); // 方法递归 间接递归 19 } 20 21 private static void test3() { 22 System.out.println("=======test3被执行========"); 23 test2(); 24 } 25 }
3、递归算法三要素大体可以总结为?
递归的公式:f(n) = f(n-1)*n;
递归的终结点:f(1)
递归的方向必须走向终结点


1 package com.itheima.d2_recusion; 2 3 /** 4 目标:递归的算法和执行流程 5 */ 6 public class RecursionDemo02 { 7 public static void main(String[] args) { 8 System.out.println(f(5)); 9 } 10 11 public static int f(int n){ 12 if(n == 1){ 13 return 1;//return n;也可以 14 }else { 15 return f(n - 1) * n; 16 } 17 } 18 }
4、递归的经典问题

1 package com.itheima.d2_recusion; 2 3 /** 4 目标 猴子吃桃。 5 6 公式(合理的): f(x) - f(x)/2 - 1 = f(x+1) 7 2f(x) - f(x) - 2 = 2f(x + 1) 8 f(x) = 2f(x + 1) + 2 9 10 求f(1) = ? 11 终结点: f(10) = 1 12 递归的方向:合理的 13 */ 14 public class RecursionDemo04 { 15 public static void main(String[] args) { 16 System.out.println(f(1)); 17 System.out.println(f(2)); 18 System.out.println(f(3)); 19 } 20 21 public static int f(int n){ 22 if(n == 10){ 23 return 1; 24 }else { 25 return 2 * f(n + 1) + 2; 26 } 27 } 28 }
5、非规律化递归案例
A、
1 package com.itheima.d2_recusion; 2 3 import java.io.File; 4 import java.io.IOException; 5 6 /** 7 目标:去D判断搜索 eDiary.exe文件 8 */ 9 public class RecursionDemo05 { 10 public static void main(String[] args) { 11 // 2、传入目录 和 文件名称 12 searchFile(new File("D:/") , "eDiary.exe"); 13 } 14 15 /** 16 * 1、搜索某个目录下的全部文件,找到我们想要的文件。 17 * @param dir 被搜索的源目录 18 * @param fileName 被搜索的文件名称 19 */ 20 public static void searchFile(File dir,String fileName){ 21 // 3、判断dir是否是目录 22 if(dir != null && dir.isDirectory()){ 23 // 可以找了 24 // 4、提取当前目录下的一级文件对象 25 File[] files = dir.listFiles(); // null [] 26 // 5、判断是否存在一级文件对象,存在才可以遍历 27 if(files != null && files.length > 0) { 28 for (File file : files) { 29 // 6、判断当前遍历的一级文件对象是文件 还是 目录 30 if(file.isFile()){ 31 // 7、是不是咱们要找的,是把其路径输出即可 32 if(file.getName().contains(fileName)){ 33 System.out.println("找到了:" + file.getAbsolutePath()); 34 // 启动它。 35 try { 36 Runtime r = Runtime.getRuntime(); 37 r.exec(file.getAbsolutePath()); 38 } catch (IOException e) { 39 e.printStackTrace(); 40 } 41 } 42 }else { 43 // 8、是文件夹,需要继续递归寻找 44 searchFile(file, fileName); 45 } 46 } 47 } 48 }else { 49 System.out.println("对不起,当前搜索的位置不是文件夹!"); 50 } 51 } 52 }
第三节 字符集
1、常见字符集底层字符的编码是什么样的?
英文和数字等在任何国家的字符集都占1个字节,并且是相同的编码
GBK字符中一个中文字符占2个字节
UTF-8编码中一个中文字符一般占3个字节
2、编码前的字符集和解码时的字符集有什么要求?
必须一致,否则会出现字符乱码
英文和数字不会乱码

===================================================================================================

=======================================================================================================

=======================================================================================================

3、字符集的编码和解码操作
A、如何使用程序对字符进行编码
String类下的方法
byte[] getBytes():默认编码
byte[] getBytes(String charsetName):制定编码
B、如何使用程序进行解码
String类的构造器
String(byte[] bytes):使用默认编码解码
String(byte[] bytes,String charsetName):指定编码解码

1 package com.itheima.d3_charset; 2 3 import java.io.UnsupportedEncodingException; 4 import java.util.Arrays; 5 6 /** 7 目标:学会自己进行文字的编码和解码,为以后可能用到的场景做准备。 8 */ 9 public class Test { 10 public static void main(String[] args) throws Exception { 11 // 1、编码:把文字转换成字节(使用指定的编码) 12 String name = "abc我爱你中国"; 13 // byte[] bytes = name.getBytes(); // 以当前代码默认字符集进行编码 (UTF-8) 14 byte[] bytes = name.getBytes("GBK"); // 指定编码 15 System.out.println(bytes.length); 16 System.out.println(Arrays.toString(bytes)); 17 18 // 2、解码:把字节转换成对应的中文形式(编码前 和 编码后的字符集必须一致,否则乱码 ) 19 // String rs = new String(bytes); // 默认的UTF-8 20 String rs = new String(bytes, "GBK"); // 指定GBK解码 21 System.out.println(rs); 22 } 23 }
第四节 IO流
1、IO流概述

2、IO流分类


3、IO流体系

4、IO流的作用
读写文件数据的
5、IO流怎么划分的,大体分为几类,各自的作用?
字节输入流InputStream(读字节数据到内存)
字节输出流OutputStream(从内存中拿出字节数据写到文件中)
字符输入流Reader (读字符数据的)
字符输出流Writer (写字符数据出去的)
6、字节流

A、字节输入流:每次读取一个字节
a、文件字节输入流,每次读取一个字节的api是哪个
public int read() 每次读取一个字节返回,如果字节已经没有可读的返回-1
b、每次读取一个字节存在什么问题
性能较慢
读取中文字符输出无法避免乱码问题


1 package com.itheima.d4_byte_stream; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.InputStream; 6 7 /** 8 目标:字节输入流的使用。 9 10 IO流的体系: 11 字节流 字符流 12 字节输入流 字节输出流 字符输入流 字符输出流 13 InputStream OutputStream Reader Writer (抽象类) 14 FileInputStream FileOutputStream FileReader FileWriter(实现类,可以使用的) 15 16 文件字节输入流:FileInputStream 17 -- 作用:以内存为基准,把磁盘文件中的数据以字节的形式读取到内存中去。 18 按照字节读文件数据到内存中。 19 -- 构造器: 20 public FileInputStream(File file):创建字节输入流管道与源文件对象接通 21 public FileInputStream(String pathname):创建字节输入流管道与源文件路径接通。 22 -- 方法: 23 public int read(): 每次读取一个字节返回,读取完毕返回-1。 24 25 小结: 26 一个一个字节读取中文数据输出其实是被淘汰的,性能极差! 27 一个一个字节读取中文数据输出,会出现截断中文字节的情况,无法避免读取中文输出乱码的问题。 28 29 */ 30 public class FileInputStreamDemo01 { 31 public static void main(String[] args) throws Exception { 32 // 1、创建一个文件字节输入流管道与源文件接通。 33 // InputStream is = new FileInputStream(new File("file-io-app\\src\\data.txt")); 34 // 简化写法 35 InputStream is = new FileInputStream("file-io-app\\src\\data.txt"); 36 37 // 2、读取一个字节返回 (每次读取一滴水) 38 // int b1 = is.read(); 39 // System.out.println((char)b1); 40 // 41 // int b2 = is.read(); 42 // System.out.println((char)b2); 43 // 44 // int b3 = is.read(); 45 // System.out.println((char)b3); 46 // 47 // int b4 = is.read(); // 读取完毕返回-1 48 // System.out.println(b4); 49 50 // 3、使用循环改进 51 // 定义一个变量记录每次读取的字节 a b 3 爱 52 // o o o [ooo] 53 int b; 54 while (( b = is.read() ) != -1){ 55 System.out.print((char) b); 56 } 57 } 58 }
B、字节输入流:每次读取一个字节数组
a、文件字节输入流,每次读取一个字节数组的api是哪个
public int read(byte[] buffer) 每次读取一个字节数组返回,如果字节已经没有可读的返回-1
b、每次读取一个字节数组存在什么问题
读取的性能得到了提升
读取中文字符输出无法避免乱码问题

1 package com.itheima.d4_byte_stream; 2 import java.io.FileInputStream; 3 import java.io.InputStream; 4 /** 5 目标:使用文件字节输入流每次读取一个字节数组的数据。 6 */ 7 public class FileInputStreamDemo02 { 8 public static void main(String[] args) throws Exception { 9 // 1、创建一个文件字节输入流管道与源文件接通 10 InputStream is = new FileInputStream("file-io-app/src/data02.txt"); 11 12 // 2、定义一个字节数组,用于读取字节数组 13 // byte[] buffer = new byte[3]; // 3B 14 // int len = is.read(buffer); 15 // System.out.println("读取了几个字节:" + len); 16 // String rs = new String(buffer); 17 // System.out.println(rs); 18 // 19 // int len1 = is.read(buffer); 20 // System.out.println("读取了几个字节:" + len1); 21 // String rs1 = new String(buffer); 22 // System.out.println(rs1); 23 // // buffer = [a b c] 24 // 25 // // buffer = [a b c] ==> [c d c] (读的文件是ab3abccd) 26 // int len2 = is.read(buffer); 27 // System.out.println("读取了几个字节:" + len2); 28 // // 读取多少倒出多少 29 // String rs2 = new String(buffer,0 ,len2); 30 // System.out.println(rs2); 31 // 32 // int len3 = is.read(buffer); 33 // System.out.println(len3); // 读取完毕返回-1 34 35 // 3、改进使用循环,每次读取一个字节数组 36 byte[] buffer = new byte[3]; 37 int len; // 记录每次读取的字节数。 38 while ((len = is.read(buffer)) != -1) { 39 // 读取多少倒出多少 40 System.out.print(new String(buffer, 0 , len)); 41 } 42 } 43 }
C、字节输入流:读取文件的全部字节
a、如何使用字节输入流读取中文内容输出不乱码呢
一次性读取完全部字节
可以定义与文件一样大的字节数组读取,也可以使用官方API
b、直接把文件数据全部读取到一个字节数组可以避免乱码,是否存在问题
如果文件过大,定义的字节数组可能引起内存溢出

1 package com.itheima.d4_byte_stream; 2 import java.io.File; 3 import java.io.FileInputStream; 4 import java.io.InputStream; 5 6 /** 7 目标:使用文件字节输入流一次读完文件的全部字节。可以解决乱码问题。 8 */ 9 public class FileInputStreamDemo03 { 10 public static void main(String[] args) throws Exception { 11 // 1、创建一个文件字节输入流管道与源文件接通 12 File f = new File("file-io-app/src/data03.txt"); 13 InputStream is = new FileInputStream(f); 14 15 // 2、定义一个字节数组与文件的大小刚刚一样大。 16 // byte[] buffer = new byte[(int) f.length()]; 17 // int len = is.read(buffer); 18 // System.out.println("读取了多少个字节:" + len); 19 // System.out.println("文件大小:" + f.length()); 20 // System.out.println(new String(buffer)); 21 22 // 读取全部字节数组 23 byte[] buffer = is.readAllBytes(); 24 System.out.println(new String(buffer)); 25 26 } 27 }
D、字节输出流:写字节数据到文件
a、字节输出流写数据的方法有哪些?
public void write(int a) 写一个字节出去
public void write(byte[] buffer) 写一个字节数组出去
public void write(byte[] buffer, int pos, int len) 写一个字节数组的一部分出去
b、字节输出流如何实现数据追加
public FileOutputStream(String filepath,boolean append) 创建字节输出流管道与源文件路径接通,可追加数据
c、字节输出流如何实现写出去的数据能换行
os.write("\r\n".get bytes())
d、如何让写出去的数据能成功生效
flush()刷新数据
close()方法是关闭流,关闭包含刷新,关闭后流不可以继续使用了。

================================================================================================

================================================================================================

1 package com.itheima.d4_byte_stream; 2 3 import java.io.File; 4 import java.io.FileNotFoundException; 5 import java.io.FileOutputStream; 6 import java.io.OutputStream; 7 8 /** 9 目标:字节输出流的使用。 10 11 IO流的体系: 12 字节流 字符流 13 字节输入流 字节输出流 字符输入流 字符输出流 14 InputStream OutputStream Reader Writer (抽象类) 15 FileInputStream FileOutputStream FileReader FileWriter (实现类) 16 17 a.FileOutputStream文件字节输出流。 18 -- 作用:以内存为基准,把内存中的数据,按照字节的形式写出到磁盘文件中去。 19 简单来说,把内存数据按照字节写出到磁盘文件中去。 20 -- 构造器: 21 public FileOutputStream(File file):创建一个字节输出流管道通向目标文件对象。 22 public FileOutputStream(String file):创建一个字节输出流管道通向目标文件路径。 23 public FileOutputStream(File file , boolean append):创建一个追加数据的字节输出流管道通向目标文件对象。 24 public FileOutputStream(String file , boolean append):创建一个追加数据的字节输出流管道通向目标文件路径。 25 -- 方法: 26 public void write(int a):写一个字节出去 。 27 public void write(byte[] buffer):写一个字节数组出去。 28 public void write(byte[] buffer , int pos , int len):写一个字节数组的一部分出去。 29 参数一,字节数组;参数二:起始字节索引位置,参数三:写多少个字节数出去。 30 小结: 31 记住。 32 换行: os.write("\r\n".getBytes()); // 换行 33 追加数据管道: OutputStream os = new FileOutputStream("day10_demo/out01.txt" , true); // 追加管道!! 34 */ 35 public class OutputStreamDemo04 { 36 public static void main(String[] args) throws Exception { 37 // 1、创建一个文件字节输出流管道与目标文件接通 38 OutputStream os = new FileOutputStream("file-io-app/src/out04.txt" , true); // 追加数据管道 39 // OutputStream os = new FileOutputStream("file-io-app/src/out04.txt"); // 先清空之前的数据,写新数据进入 40 41 // 2、写数据出去 42 // a.public void write(int a):写一个字节出去 43 os.write('a'); 44 os.write(98); 45 os.write("\r\n".getBytes()); // 换行 46 // os.write('徐'); // [ooo] 47 48 // b.public void write(byte[] buffer):写一个字节数组出去。 49 byte[] buffer = {'a' , 97, 98, 99}; 50 os.write(buffer); 51 os.write("\r\n".getBytes()); // 换行 52 53 byte[] buffer2 = "我是中国人".getBytes(); 54 // byte[] buffer2 = "我是中国人".getBytes("GBK"); 55 os.write(buffer2); 56 os.write("\r\n".getBytes()); // 换行 57 58 59 // c. public void write(byte[] buffer , int pos , int len):写一个字节数组的一部分出去。 60 byte[] buffer3 = {'a',97, 98, 99}; 61 os.write(buffer3, 0 , 3); 62 os.write("\r\n".getBytes()); // 换行 63 64 // os.flush(); // 写数据必须,刷新数据 可以继续使用流 65 os.close(); // 释放资源,包含了刷新的!关闭后流不可以使用了 66 } 67 }
E、文件拷贝
a、字节流适合做一切文件数据的拷贝吗
任何文件的底层都是字节,拷贝是一字不漏的转移字节,只要前后文件格式、编码一致没有任何问题

===================================================================================================

1 package com.itheima.d4_byte_stream; 2 3 import java.io.FileInputStream; 4 import java.io.FileOutputStream; 5 import java.io.InputStream; 6 import java.io.OutputStream; 7 8 /** 9 * 目标:学会使用字节流完成文件的复制(支持一切文件类型的复制) 10 */ 11 public class CopyDemo05 { 12 public static void main(String[] args) { 13 try { 14 // 1、创建一个字节输入流管道与原视频接通 15 InputStream is = new FileInputStream("file-io-app/src/out04.txt"); 16 17 // 2、创建一个字节输出流管道与目标文件接通 18 OutputStream os = new FileOutputStream("file-io-app/src/out05.txt"); 19 20 // 3、定义一个字节数组转移数据 21 byte[] buffer = new byte[1024]; 22 int len; // 记录每次读取的字节数。 23 while ((len = is.read(buffer)) != -1){ 24 os.write(buffer, 0 , len); 25 } 26 System.out.println("复制完成了!"); 27 28 // 4、关闭流。 29 os.close(); 30 is.close(); 31 } catch (Exception e){ 32 e.printStackTrace(); 33 } 34 } 35 }
7、资源释放的两种方式
A、try-catch-finally的作用
finally代码块是最终一定要执行的,可以在代码执行完毕的最后用于释放资源,就算你try里面有return,finally也要先执行,在返回try里面的return,除非try里面把虚拟机直接干掉。

1 package com.itheima.d5_resource; 2 3 import java.io.*; 4 5 /** 6 * 目标:学会使用finally释放资源。 7 */ 8 public class TryCatchFinallyDemo1 { 9 public static void main(String[] args) { 10 InputStream is = null; 11 OutputStream os = null; 12 try { 13 14 // System.out.println(10/ 0); 15 16 // 1、创建一个字节输入流管道与原视频接通 17 is = new FileInputStream("file-io-app/src/out04.txt"); 18 19 // 2、创建一个字节输出流管道与目标文件接通 20 os = new FileOutputStream("file-io-app/src/out05.txt"); 21 22 // 3、定义一个字节数组转移数据 23 byte[] buffer = new byte[1024]; 24 int len; // 记录每次读取的字节数。 25 while ((len = is.read(buffer)) != -1){ 26 os.write(buffer, 0 , len); 27 } 28 System.out.println("复制完成了!"); 29 30 // System.out.println( 10 / 0); 31 32 } catch (Exception e){ 33 e.printStackTrace(); 34 } finally { 35 // 无论代码是正常结束,还是出现异常都要最后执行这里 36 System.out.println("========finally========="); 37 try { 38 // 4、关闭流。 39 if(os!=null)os.close(); 40 } catch (IOException e) { 41 e.printStackTrace(); 42 } 43 try { 44 if(is != null) is.close(); 45 } catch (IOException e) { 46 e.printStackTrace(); 47 } 48 } 49 50 System.out.println(test(10, 2)); 51 } 52 53 public static int test(int a , int b){ 54 try { 55 int c = a / b; 56 return c; 57 }catch (Exception e){ 58 e.printStackTrace(); 59 return -111111; // 计算出现bug. 60 }finally { 61 System.out.println("--finally--"); 62 // 哪怕上面有return语句执行,也必须先执行完这里才可以! 63 // 开发中不建议在这里加return ,如果加了,返回的永远是这里的数据了,这样会出问题! 64 return 100; 65 } 66 } 67 }
B、try-catch-resource的作用
自动释放资源、代码简洁

============================================================================================

1 package com.itheima.d5_resource; 2 3 import java.io.*; 4 5 /** 6 * 目标:学会使用JDK 7的新方式释放资源 7 */ 8 public class TryCatchResouceDemo2 { 9 public static void main(String[] args) { 10 11 try ( 12 // 这里面只能放置资源对象,用完会自动关闭:自动调用资源对象的close方法关闭资源(即使出现异常也会做关闭操作) 13 // 1、创建一个字节输入流管道与原视频接通 14 InputStream is = new FileInputStream("file-io-app/src/out04.txt"); 15 // 2、创建一个字节输出流管道与目标文件接通 16 OutputStream os = new FileOutputStream("file-io-app/src/out05.txt"); 17 18 // int age = 23; // 这里只能放资源 19 MyConnection connection = new MyConnection(); // 最终会自动调用资源的close方法 20 ) { 21 22 // 3、定义一个字节数组转移数据 23 byte[] buffer = new byte[1024]; 24 int len; // 记录每次读取的字节数。 25 while ((len = is.read(buffer)) != -1){ 26 os.write(buffer, 0 , len); 27 } 28 System.out.println("复制完成了!"); 29 30 } catch (Exception e){ 31 e.printStackTrace(); 32 } 33 34 } 35 } 36 37 class MyConnection implements AutoCloseable{ 38 @Override 39 public void close() throws IOException { 40 System.out.println("连接资源被成功释放了!"); 41 } 42 }
1 package com.itheima.d5_resource; 2 3 import java.io.*; 4 5 /** 6 * 目标:JDK 9释放资源的方式:可以了解下。 7 */ 8 public class TryCatchResouceDemo3 { 9 public static void main(String[] args) throws Exception { 10 11 // 这里面只能放置资源对象,用完会自动关闭:自动调用资源对象的close方法关闭资源(即使出现异常也会做关闭操作) 12 // 1、创建一个字节输入流管道与原视频接通 13 InputStream is = new FileInputStream("file-io-app/src/out04.txt"); 14 // 2、创建一个字节输出流管道与目标文件接通 15 OutputStream os = new FileOutputStream("file-io-app/src/out05.txt"); 16 try ( is ; os ) { 17 // 3、定义一个字节数组转移数据 18 byte[] buffer = new byte[1024]; 19 int len; // 记录每次读取的字节数。 20 while ((len = is.read(buffer)) != -1){ 21 os.write(buffer, 0 , len); 22 } 23 System.out.println("复制完成了!"); 24 25 } catch (Exception e){ 26 e.printStackTrace(); 27 } 28 } 29 }
8、字符流
A、字符输入流-一次读取一个字符
a、文件字符输入流,每次读取一个字符的api是哪个
public int read()
b、字符流的好处,每次读取一个字符存在什么问题
读取中文字符不会出现乱码(如果代码文件编码一致)
性能较慢

===============================================================================================

1 package com.itheima.d6_char_stream; 2 3 import java.io.File; 4 import java.io.FileReader; 5 import java.io.Reader; 6 7 /** 8 目标:字符输入流的使用。 9 10 IO流的体系: 11 字节流 字符流 12 字节输入流 字节输出流 字符输入流 字符输出流 13 InputStream OutputStream Reader Writer (抽象类) 14 FileInputStream FileOutputStream FileReader FileWriter (实现类) 15 16 c.FileReader:文件字符输入流。 17 -- 作用:以内存为基准,把磁盘文件的数据以字符的形式读入到内存。 18 简单来说,读取文本文件内容到内存中去。 19 20 -- 构造器: 21 public FileReader(File file):创建一个字符输入流与源文件对象接通。 22 public FileReader(String filePath):创建一个字符输入流与源文件路径接通。 23 24 -- 方法: 25 public int read(): 读取一个字符的编号返回! 读取完毕返回-1 26 public int read(char[] buffer):读取一个字符数组,读取多少个字符就返回多少个数量,读取完毕返回-1 27 小结: 28 字符流一个一个字符的读取文本内容输出,可以解决中文读取输出乱码的问题。 29 字符流很适合操作文本文件内容。 30 但是:一个一个字符的读取文本内容性能较差!! 31 */ 32 public class FileReaderDemo01 { 33 public static void main(String[] args) throws Exception { 34 // 目标:每次读取一个字符。 35 // 1、创建一个字符输入流管道与源文件接通 36 Reader fr = new FileReader("file-io-app\\src\\data06.txt"); 37 38 // 2、读取一个字符返回,没有可读的字符了返回-1 39 // int code = fr.read(); 40 // System.out.print((char)code); 41 // 42 // int code1 = fr.read(); 43 // System.out.print((char)code1); 44 45 // 3、使用循环读取字符 46 int code; 47 while ((code = fr.read()) != -1){ 48 System.out.print((char) code); 49 } 50 } 51 }
B、字符输入流-一次读取一个字符数组
a、文件字符输入流,每次读取一个字符数组的api是哪个
public int read(char[] buffer) 每次读取一个字符数组,返回读取的字符个数,如果字符已经没有可读的返回-1
b、每次读取一个字符数组的优势
读取的性能得到了提升
读取中文字符输出不会乱码

==================================================================================================

1 package com.itheima.d6_char_stream; 2 3 import java.io.FileReader; 4 import java.io.Reader; 5 6 /** 7 目标:字符输入流的使用-按照字符数组读取。 8 9 IO流的体系: 10 字节流 字符流 11 字节输入流 字节输出流 字符输入流 字符输出流 12 InputStream OutputStream Reader Writer (抽象类) 13 FileInputStream FileOutputStream FileReader FileWriter (实现类) 14 15 c.FileReader:文件字符输入流。 16 -- 作用:以内存为基准,把磁盘文件的数据以字符的形式读入到内存。 17 简单来说,读取文本文件内容到内存中去。 18 -- 构造器: 19 public FileReader(File file):创建一个字符输入流与源文件对象接通。 20 public FileReader(String filePath):创建一个字符输入流与源文件路径接通。 21 -- 方法: 22 public int read(): 读取一个字符的编号返回! 读取完毕返回-1 23 public int read(char[] buffer):读取一个字符数组, 24 读取多少个字符就返回多少个数量,读取完毕返回-1 25 小结: 26 字符流按照字符数组循环读取数据,可以解决中文读取输出乱码的问题,而且性能也较好!! 27 */ 28 public class FileReaderDemo02 { 29 public static void main(String[] args) throws Exception { 30 // 1、创建一个文件字符输入流与源文件接通 31 Reader fr = new FileReader("file-io-app/src/data07.txt"); 32 33 // 2、用循环,每次读取一个字符数组的数据。 1024 + 1024 + 8 34 char[] buffer = new char[1024]; // 1K字符 35 int len; 36 while ((len = fr.read(buffer)) != -1) { 37 String rs = new String(buffer, 0, len); 38 System.out.print(rs); 39 } 40 41 } 42 }
C、字符输出流
a、字符输出流写数据的方法有哪些

b、字符输出流如何实现数据追加
public FileWriter(String filepath,boolean append) 创建字符输出流管道与源文件路径接通,可追加数据
c、字符输出流如何实现写出去的数据能换行
fw.writer("\r\n")
d、字符输出流如何实现写出去的数据刷新
flush()刷新数据
close()方法是关闭流,关闭包含刷新,关闭后流不可以继续使用了
e、字节流、字符流的使用场景总结
字节流适合做一切文件数据的拷贝(音视频,文本)
字节流不适合读取中文内容那个输出
字符流适合做文本文件的操作(读,写)

==============================================================================================

================================================================================================

1 package com.itheima.d6_char_stream; 2 3 import java.io.File; 4 import java.io.FileWriter; 5 import java.io.Writer; 6 7 /** 8 目标:字符输出流的使用。 9 10 IO流的体系: 11 字节流 字符流 12 字节输入流 字节输出流 字符输入流 字符输出流 13 InputStream OutputStream Reader Writer (抽象类) 14 FileInputStream FileOutputStream FileReader FileWriter (实现类) 15 16 d.FileWriter文件字符输出流的使用。 17 -- 作用:以内存为基准,把内存中的数据按照字符的形式写出到磁盘文件中去。 18 简单来说,就是把内存的数据以字符写出到文件中去。 19 -- 构造器: 20 public FileWriter(File file):创建一个字符输出流管道通向目标文件对象。 21 public FileWriter(String filePath):创建一个字符输出流管道通向目标文件路径。 22 public FileWriter(File file,boolean append):创建一个追加数据的字符输出流管道通向目标文件对象。 23 public FileWriter(String filePath,boolean append):创建一个追加数据的字符输出流管道通向目标文件路径。 24 -- 方法: 25 a.public void write(int c):写一个字符出去 26 b.public void write(String c)写一个字符串出去: 27 c.public void write(char[] buffer):写一个字符数组出去 28 d.public void write(String c ,int pos ,int len):写字符串的一部分出去 29 e.public void write(char[] buffer ,int pos ,int len):写字符数组的一部分出去 30 小结: 31 字符输出流可以写字符数据出去,总共有5个方法写字符。 32 覆盖管道: 33 Writer fw = new FileWriter("Day10Demo/src/dlei03.txt"); // 覆盖数据管道 34 追加数据管道: 35 Writer fw = new FileWriter("Day10Demo/src/dlei03.txt",true); // 追加数据管道 36 换行: 37 fw.write("\r\n"); // 换行 38 结论:读写字符文件数据建议使用字符流。复制文件建议使用字节流。 39 */ 40 public class FileWriterDemo03 { 41 public static void main(String[] args) throws Exception { 42 // 1、创建一个字符输出流管道与目标文件接通 43 // Writer fw = new FileWriter("file-io-app/src/out08.txt"); // 覆盖管道,每次启动都会清空文件之前的数据 44 Writer fw = new FileWriter("file-io-app/src/out08.txt", true); // 覆盖管道,每次启动都会清空文件之前的数据 45 46 // a.public void write(int c):写一个字符出去 47 fw.write(98); 48 fw.write('a'); 49 fw.write('徐'); // 不会出问题了 50 fw.write("\r\n"); // 换行 51 52 // b.public void write(String c)写一个字符串出去 53 fw.write("abc我是中国人"); 54 fw.write("\r\n"); // 换行 55 56 57 // c.public void write(char[] buffer):写一个字符数组出去 58 char[] chars = "abc我是中国人".toCharArray(); 59 fw.write(chars); 60 fw.write("\r\n"); // 换行 61 62 63 // d.public void write(String c ,int pos ,int len):写字符串的一部分出去 64 fw.write("abc我是中国人", 0, 5); 65 fw.write("\r\n"); // 换行 66 67 68 // e.public void write(char[] buffer ,int pos ,int len):写字符数组的一部分出去 69 fw.write(chars, 3, 5); 70 fw.write("\r\n"); // 换行 71 72 73 // fw.flush();// 刷新后流可以继续使用 74 fw.close(); // 关闭包含刷线,关闭后流不能使用 75 76 } 77 }

浙公网安备 33010602011771号