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 }
File对象创建

      \  叫做反斜杠   一般写路径要在这个前面再加一个反斜杠,告诉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 }
File类常用API

    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 }
File类的遍历功能

第二节  方法递归

  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 }
try-catch-finally

    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 }
JDK7
 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 }
JDK9

  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 }
字符输出流
posted @ 2022-09-07 17:55  漫漫修行路  阅读(73)  评论(0)    收藏  举报