十五、IO流【黑马JavaSE笔记】(本文文中记录了个人学习感受)

2022-11-23 17:43:52 浏览数 (1)

文章目录
  • IO流
  • (一)File
    • 1.File类的概述和构造方法
    • 2.File类的创建功能
    • 3.File类判断和获取功能
    • 4.File类的删除功能
    • 5.递归
    • 6.案例(递归求阶乘)
    • 7.案例(遍历目录)
  • (二)字节流
    • 1.IO流概述和分类
    • 2.字节流写数据
    • 3.字节流写数据的3种方式
    • 4.字节流写数据的两个小问题
      • (1)字节流写数据如何实现换行?
      • (2)字节流写数据如何实现追加写入5.字节流写数据加异常处理
    • 6.字节流读数据(一次读一个字节)
    • 7.案例(复制文本文件)
    • 8.字节流读数据(一次读一个字节数组数据)
    • 9.字节流复制图片
    • 10.字节缓冲流
    • 11.案例(复制视频)
  • (三)字符流
    • 1.为什么会出现字符流
    • 2.编码表
    • 3.字符串中的编码解码问题
    • 4.字符流中的编码解码问题
    • 5.字符流写数据的5种方式
    • 6.字符流读数据的2种方式
    • 7.案例(字符流复制文件)
    • 8.字符流读写数据的简化形式
    • 9.字符缓冲流
    • 10.字符缓冲流特有功能(推荐使用)
    • 11.案例(字符缓冲流特有功能复制Java文件)
  • (四)IO流小结
  • (五)案例
    • 1.集合到文件
    • 2.文件到集合
    • 3.点名器
    • 4.集合到文件(升级版)
    • 5.文件到集合(升级版)
    • 6.集合到文件(数据排序升级版)
    • 7.复制单级文件夹
    • 8.复制多级文件夹
  • (六)复制文件的异常处理
  • (七)特殊操作流
    • 1.标准输入流
    • 2.标准输出流
    • 3.打印流
      • (1)字节打印流(PrintStream)
      • (2)字符打印流(PrintWriter)
    • 4.复制Java文件(打印流改进版)
    • 5.对象序列化流
      • (1)对象序列化流
      • (2)对象反序列化流
      • (3)对象序列化的三个问题
    • 6.Properties
    • 7.Properties与IO流结合的方法
    • 8.案例(游戏次数)

IO流

(一)File

1.File类的概述和构造方法

代码演示:

代码语言:javascript复制
import java.io.File;

public class FileDemo {
    public static void main(String[] args) {
        File f = new File("E:\Temp\java.txt");
        System.out.println(f);  //E:\Temp\java.txt
        File f2 = new File("E:\Temp","java.txt");
        System.out.println(f2);  //E:\Temp\java.txt
        File f3 = new File("E:\Temp");
        File f4 = new File(f3,"java.txt");
        System.out.println(f4);  //E:\Temp\java.txt
    }
}

2.File类的创建功能

注意:

  • 单个目录创建用mkdir(),多个目录创建用mkdirs()
  • 创建文件就用创建文件的方法,创建目录就用创建目录的方法,不能用创建目录的方法同时创建文件,反之也不行(例如本应该创建文件,结果使用了创建目录的方法,即使返回值为true,创建的是目录而不是文件,所以不能这样写)
  • 同一个目录下的目录和文件不能重名,否则会创建不成功,返回false

3.File类判断和获取功能

4.File类的删除功能
  • public boolean delete() 删除由此抽象路径名表示的文件或目录

绝对路径和相对路径的区别

  • 绝对路径:完整的路径名,不需要任何其他信息就可以定位它所表示的文件。例如:E:\Temp\java.txt
  • 相对路径:必须使用取自其他路径的信息进行解释。例如:Temp\java.txt

注意:

  • 如果想要删除的目录下有内容,不能直接删除,应先删除目录里面的内容,再删除这个目录

5.递归

递归概述:以编程的角度来看,递归指的是方法定义中调用方法本身的现象

递归解决问题的思路:

把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解

递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算

递归解决问题要找到两个内容:

  • 递归出口:否则会出现内存溢出
  • 递归原则:与原问题相似的规模较小的问题

6.案例(递归求阶乘)
代码语言:javascript复制
public class FileDemo {
    public static void main(String[] args) {
        System.out.println(multiply(3));
    }

    public static int multiply(int num) {
        if(num == 1){
            return 1;
        }else {
            return num * multiply(num - 1);
        }
    }
}
7.案例(遍历目录)
代码语言:javascript复制
import java.io.File;

public class FileDemo2 {
    public static void main(String[] args) {
        //根据给定路径创建一个File对象
        File f = new File("F:\");

        //调用方法
        getAllFile(f);
    }

    //遍历给定路径下的所有文件绝对路径的方法
    public static void getAllFile(File f) {
        //给定路径下的所有的文件或者目录的File数组
        File[] fileArray = f.listFiles();
        //增加判断条件,如果给定路径下数组不是空的,则进行遍历
        if(fileArray != null){
            for(File file : fileArray) {
                if(file.isFile()) {     //如果它是一个文件,那么就输出绝对路径
                    System.out.println(file.getAbsolutePath());
                } else {    //如果是文件夹,那么就递归调用方法
                    getAllFile(file);
                }
            }
        }
    }
}


(二)字节流

1.IO流概述和分类

IO流概述:

  • IO:输入/输出(Input/Output)
  • 流:是一种抽象概念,是对数据传输的总称。也就是说数据在设备间的传输称为流,流的本质是数据传输
  • IO流就是用来处理设备间数据传输问题的 ​ 常见的应用:文件复制;文件上传;文件下载

IO流分类:

  • 按照数据的流向 ​ 输入流:读数据 ​ 输出流:写数据
  • 按照数据类型来分 ​ 字节流 ​ 字节输入流;字节输出流 ​ 字符流 ​ 字符输入流;字符输出流

一般来说,我们说IO流的分类是按照数据类型来分

那么这两种流都在什么情况下使用呢?

  • 如果数据通过Window自带的记事本软件打开,我们还可以读懂里面的内容,就是用字符流,否则使用字节流。如果你不知道该使用那种类型的流,就使用字节流

2.字节流写数据

字节流抽象基类

  • InputStream:这个抽象类是表示字节输入流的所有类的超类
  • OutputStream:这个抽象类是表示字节输出流的所有的超类
  • 子类名特点:子类名称都是以其父类名作为子类名的后缀

FileOutputStream:文件输出流用于将数据写入File

  • FileOutputStream(String name) :创建文件输出流以指定的名称写入文件

使用字节输出流写数据的步骤:

  • 创建字节输出流对象(调用系统功能创建了对象,创建字节输出流对象,让字节输出流对象指向文件)
  • 调用字节输出流对象的写数据方法
  • 释放资源(关闭此文件输出流并释放与此流相关联的任何系统资源)

代码演示:

代码语言:javascript复制
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamDemo {
    public static void main(String[] args) throws IOException {
        //创建字节流输出对象
        //File f = new File("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP25\fos.txt");
        //FileOutputStream fos = new FileOutputStream(f);
        //FileOutputStream fos = new FileOutputStream(new File("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP25\fos.txt"));
        
        FileOutputStream fos = new FileOutputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP25\fos.txt");//这一行与上面三行是等价的,这个写法最简单

        //void write(int b):将指定的字节写入此文件输出流
        fos.write(50);

        //最后都要释放资源
        //void close():关闭此文件输出流并释放与此流相关联的任何系统资源
        fos.close();
    }
}

3.字节流写数据的3种方式

代码演示:

代码语言:javascript复制
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamDemo {
    public static void main(String[] args) throws IOException {
        //创建字节流输出对象
        FileOutputStream fos  = new FileOutputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP25\fos.txt");

        //void write(int b)
        fos.write(50);//2
        fos.write(51);//3
        fos.write(52);//4

        //void write(byte[] b)
        /* byte[] b = {53,54,55,56};
        fos.write(b);//5678 */
        String s = "abcde";
        byte[] bytes = s.getBytes();
        fos.write(bytes);//abcde

        //void write(byte[] b,int off,int len)
        fos.write(bytes,1,3);//bcd
        
        //最后都要释放资源
        fos.close();
    }
}

4.字节流写数据的两个小问题
(1)字节流写数据如何实现换行?
  • 写完数据后,加换行符 ​ windows: rn ​ linux: n ​ mac: r
(2)字节流写数据如何实现追加写入?
  • public FileOutputStream(String name,boolean append)
  • 创建文件输出流以指定的名称写入文件。如果第二个参数为true,则字节流写入文件的末尾而不是开头

代码演示:

代码语言:javascript复制
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamDemo {
    public static void main(String[] args) throws IOException {
        //创建字节流输出对象,增加第二参数为true,实现追加写入的功能
        FileOutputStream fos = new FileOutputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP25\fos.txt", true);
        //写数据
        for (int i = 0; i < 10; i  ) {
            fos.write("abcde".getBytes());
            fos.write("rn".getBytes());
        }
        //释放资源
        fos.close();
    }
}

5.字节流写数据加异常处理

finally:在异常处理时提供finally块来执行所有清除操作。比如说IO流中的释放资源

特点:被finally控制的语句一定会执行,除非JVM退出

代码语言:javascript复制
try{
	可能出现异常的代码
} catch (异常类名 变量名) {
    异常的处理代码;
} finally {
    执行所有清除操作;
}

代码演示:

代码语言:javascript复制
import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamDemo {
    public static void main(String[] args) {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP25\fos.txt");
            fos.write("abcde".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(fos != null){    //判断如果fos不是空的则进行资源释放(增加代码的健壮性),如果不进行判断可能会造成空指针异常
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

6.字节流读数据(一次读一个字节)

需求:把文件fos.txt的内容读出来在控制台输出

FileInputStream:从文件系统中的文件获取输入字节

  • FileInputStream(String name) :通过打开与实际文件的连接来创建一个FileInputStream,该文件由文件系统中的路径名name命名

使用字节输入流读数据的步骤:

1.创建字节输入流对象

2.调用字节输入流对象的读数据方法

3.释放资源

代码演示:

代码语言:javascript复制
import java.io.FileInputStream;
import java.io.IOException;

public class FileInputStreamDemo {
    public static void main(String[] args) throws IOException {
        //创建字节流读数据的对象
        FileInputStream fis = new FileInputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP25\fos.txt");

        //读数据
        /*
        int by = fis.read();
        while(by != -1) {
            System.out.print((char)by); //此处用print 不用println
            by = fis.read();
        }
        */
        //简化上述代码
        int by;
        while ((by = fis.read()) != -1) {
            System.out.print((char) by);
        }
        //释放资源
        fis.close();
    }
}

7.案例(复制文本文件)

代码实现:

代码语言:javascript复制
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyDemo {
    public static void main(String[] args) throws IOException {
        //创建输入输出流对象
        FileOutputStream fos = new FileOutputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP25\fos_copy.txt");
        FileInputStream fis = new FileInputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP25\fos.txt");

        //读取数据并写入数据
        int by;
        while((by = fis.read()) != -1) {
            fos.write(by);
        }

        //释放资源
        fos.close();
        fis.close();
    }
}

8.字节流读数据(一次读一个字节数组数据)

需求:把文件fos.txt中的内容读取出来在控制台输出

使用字节输入流读数据的步骤:

1.创建字节输入流对象

2.调用字节输入流对象的读数据方法

3.释放资源

代码演示:

代码语言:javascript复制
import java.io.FileInputStream;
import java.io.IOException;

public class FileInputStreamDemo2 {
    public static void main(String[] args) throws IOException {
        //创建字节输入流的对象
        FileInputStream fis = new FileInputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP25\fos.txt");
        //读数据
        byte[] bys = new byte[1024];//1024及其整数倍
        int len;
        while((len = fis.read(bys)) != -1){
            System.out.print(new String(bys,0,len));
        }
        //释放资源
    fis.close();
    }
}

9.字节流复制图片

代码演示:

代码语言:javascript复制
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyJpgDemo {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP25\头像.jpg");
        FileOutputStream fos = new FileOutputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP25\头像Copy.jpg");

        byte[] bys = new byte[1024];
        int len;
        while ((len = fis.read(bys)) != -1) {
            fos.write(bys, 0, len);
        }

        fis.close();
        fos.close();
    }
}

10.字节缓冲流

代码演示:

代码语言:javascript复制
import java.io.*;

public class BufferStreamDemo {
    public static void main(String[] args) throws IOException {
       /*
       FileOutputStream fos = new FileOutputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP25\Bos.txt");
       BufferedOutputStream bos = new BufferedOutputStream(fos);
        */
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP25\Bos.txt"));
        bos.write("hellon".getBytes());
        bos.write("worldn".getBytes());

        bos.close();

        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP25\Bos.txt"));

        //一次读一个字节
       /* int by;
        while ((by = bis.read()) != -1) {
            System.out.print((char) by);
        }*/

        //一次读一组字节
        byte[] bys = new byte[1024];
        int len;
        while ((len = bis.read(bys)) != -1) {
            System.out.println(new String(bys, 0, len));
        }

        bis.close();
    }

11.案例(复制视频)

代码实现:

代码语言:javascript复制
import java.io.*;

public class CopyMP4Demo {
    public static void main(String[] args) throws IOException {
        //记录开始时间
        long startTime = System.currentTimeMillis();

        //创建字节输入输出流对象
        FileInputStream fis = new FileInputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP25\素材.mp4");
        FileOutputStream fos = new FileOutputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP25\素材copy.mp4");

        //读取数据并写入数据
        //1.基本字节流一次读写一个字节
        /*int dy;
        while ((dy = fis.read()) != -1) {
            fos.write(dy);
        } //共耗时:5006毫秒*/

        //2.基本字节流一次读写一个字节数组
        /*byte[] bys = new byte[1024];
        int len;
        while ((len = fis.read(bys)) != -1) {
            fos.write(bys, 0, len);
        }   //共耗时:9毫秒*/

        //3.字节缓冲流一次读写一个字节
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP25\素材.mp4"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP25\素材copy.mp4"));

       /* int by;
        while ((by = bis.read()) != -1) {
            bos.write(by);
        }   //共耗时:35毫秒*/

        //4.字节缓冲流一次读写一个字节数组
        byte[] bys2 = new byte[1024];
        int len2;
        while ((len2 = bis.read(bys2)) != -1) {
            bos.write(bys2, 0, len2);
        }   //共耗时:3毫秒

        //释放资源
        /*fis.close();
        fos.close();*/
        bis.close();
        bos.close();

        //记录结束时间
        long endTime = System.currentTimeMillis();
        System.out.println("共耗时:"   (endTime - startTime)   "毫秒");
    }
}

总结:四种读写方式中字节缓冲流一次读写一个字节数组是最快的方式基本字节流一次读写一个字符是最慢的



(三)字符流

1.为什么会出现字符流

由于字节流操作中文不是特别方便,所以Java就提供字符流

  • 字符流 = 字节流 编码表(UTF-8 中文占3个字节 GBK中文占2个字节)

用字节流复制文本文件时,文本文件也会有中文,但是没问题,原因是最终底层操作会自动进行字节拼接成中文,如何识别中文的呢?

  • 汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数

2.编码表

基础知识:

  • 计算机中存储的信息都是用二进制数表示的;我们在屏幕上看到的英文、汉字等字符是二进制数转换之后的结果
  • 按照某种规则,将字符存储到计算机中,称为编码。反之,将存储在计算机中的二进制数按照某种规则解析显示出来,称为解码。这里强调以下:按照A编码存储,必须按照A编码解析,这样才能显示正确的文本符号。否则就会导致乱码现象 字符编码:就是一套自然语言的字符与二进制数之间的对应规则(A,65)

字符集:

  • 是一个系统支持的所有字符的集合,包括个国家文字、标点符号、图形符号、数字等
  • 计算机要准确的存储和识别各种字符集符号,就需要进行字符编码,一套字符集必然至少有一套字符编码。 常见字符集有ASCll字符集、GBXXX字符集、Unicode字符集

3.字符串中的编码解码问题

代码演示:

代码语言:javascript复制
import java.io.UnsupportedEncodingException;
import java.util.Arrays;

public class StringDemo {
    public static void main(String[] args) throws UnsupportedEncodingException {
        //由此可见IDEA平台默认的编码和解码为UTF-8
        String s = "中国";
        //编码
        byte[] bys = s.getBytes();  //[-28, -72, -83, -27, -101, -67]
        byte[] bys2 = s.getBytes("UTF-8");//[-28, -72, -83, -27, -101, -67]
        byte[] bys3 = s.getBytes("GBK");//[-42, -48, -71, -6]

        System.out.println(Arrays.toString(bys3));

        //解码
        String ss = new String(bys);//中国
        String ss2 = new String(bys,"UTF-8");//中国
        String ss3 = new String (bys,"GBK");//涓浗
        System.out.println(ss3);
    }
}

4.字符流中的编码解码问题

字符流抽象基类

  • Reader:字符输入流的抽象类
  • Writer:字符输出流的抽象类

字符流中和编码解码问题相关的两个类:

  • InputStreamReader
  • OutputStreamWriter

构造方法:

  • InputStreamReader(InputStream in) 创建一个inputstreamreader使用默认字符集。
  • InputStreamReader(InputStream in, Charset cs) 创建一个inputstreamreader使用给定的字符集。
  • OutputStreamWriter(OutputStream out) 创建一个outputstreamwriter使用默认的字符编码。
  • OutputStreamWriter(OutputStream out, Charset cs) 创建一个outputstreamwriter使用给定的字符集。

代码演示:

代码语言:javascript复制
import java.io.*;

public class ConversionStreamDemo {
    public static void main(String[] args) throws IOException {
        //OutputStreamWriter(OutputStream out)
//        FileOutputStream fos = new FileOutputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP26\fos.txt");
//        OutputStreamWriter osw = new OutputStreamWriter(fos);
//        OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP26\fos.txt"));
        //OutputStreamWriter(OutputStream out, Charset cs)
        OutputStreamWriter osw3 = new OutputStreamWriter(new FileOutputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP26\fos.txt"), "GBK");

        osw3.write("中国");//�й�  IDEA默认为UTF-8 使用GBK文本就会乱码
        osw3.close();


        //InputStreamReader(InputStream in)
//        FileInputStream fis = new FileInputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP26\fos.txt");
//        InputStreamReader isr = new InputStreamReader(fis);
//        InputStreamReader isr2 = new InputStreamReader(new FileInputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP26\fos.txt"))
        InputStreamReader isr3 = new InputStreamReader(new FileInputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP26\fos.txt"),"GBK");
        int ch;
        while ((ch = isr3.read()) != -1) {
            System.out.print((char)ch);//中国   读数据的时候也要用GBK解码才能;正确显示
        }
        isr3.close();

    }
}

5.字符流写数据的5种方式

代码演示:

代码语言:javascript复制
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class OutputStreamWriterDemo {
    public static void main(String[] args) throws IOException {
        OutputStreamWriter osw  = new OutputStreamWriter(new FileOutputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP26\fos.txt"));
        osw.write(66);//此时如果不刷新就会停留在字符缓冲区,在文本中显示不出来
        //flush()  刷新流
//        osw.flush();

        char[] chs = {'a','b','c','d','e'};
        osw.write(chs);

        osw.write(chs,0,chs.length);

        osw.write("中国");
        osw.write("中国666",0,"中国666".length());
        osw.close();//在关闭流前会进行一次刷新
    }
}

6.字符流读数据的2种方式
  • int read() 一次读一个字符数据
  • int read(char[] cbuf) 一次读一个字符数组数据

代码演示:

代码语言:javascript复制
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class InputStreamReaderDemo {
    public static void main(String[] args) throws IOException {
        InputStreamReader isr = new InputStreamReader(new FileInputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP26\fos.txt"));
        //一次读一个字符数据
        int ch;
        while ((ch = isr.read()) != -1) {
            System.out.print((char) ch);
        }

        //一次读一个字符数据数组
        char[] chs = new char[1024];
        int len;
        while((len = isr.read(chs))!=-1){
            System.out.println(new String(chs,0,len));
        }
        //释放资源
        isr.close();
    }
}

7.案例(字符流复制文件)

代码实现:

代码语言:javascript复制
import java.io.*;

public class ConversionStreamDemo2 {
    public static void main(String[] args) throws IOException {
        //创建字符输入输出流对象
        InputStreamReader itr = new InputStreamReader(new FileInputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP26\fos.txt"));
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP26\fosCopy.txt"));

        //读写数据
        //一次读一个字符
        int ch;
        while ((ch = itr.read()) != -1) {
            osw.write(ch);
        }

        //一次读一个字符数据数组
        char[] chs = new char[1024];
        int len;
        while ((len = itr.read(chs)) != -1) {
            osw.write(chs,0,len);
        }

        //释放资源
        itr.close();
        osw.close();
    }
}

8.字符流读写数据的简化形式

转换流的名字比较长,所以为了简化书写,转化流提供了对应的子类

  • FIleReader:用于读取字符文件的便捷类
    • FileReader(String fileName)
  • FileWriter:用于书写字符文件的便捷类
    • FileWriter(String fileName)

注意当需要改变编码时还需使用转换流(InputStreamReader和OutputStreamWriter)

代码演示:

代码语言:javascript复制
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CopyJavaDemo {
    public static void main(String[] args) throws IOException {
        //创建字符转化流子类对象
        FileReader fr= new FileReader("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP26\StringDemo.java");
        FileWriter fw = new FileWriter("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP26\CopyStringDemo.java");

        //读写数据
        int ch;
        while((ch = fr.read())!=-1){
            fw.write(ch);
        }

        char[] chs = new char[1024];
        int len;
        while((len = fr.read(chs))!=-1){
            fw.write(chs,0,len);
        }

        //释放资源
        fr.close();
        fw.close();
    }
}

9.字符缓冲流

代码演示:

代码语言:javascript复制
import java.io.*;

public class BufferStreamDemo {
    public static void main(String[] args) throws IOException {
        //创建字符缓冲对象
        BufferedReader bf = new BufferedReader(new FileReader("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP26\fos.txt"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP26\Copy_fos.txt"));

        //读写数据
        //第一种
        int ch;
        while((ch = bf.read())!=-1){
            bw.write(ch);
        }

        //第二种
        char[] chs = new char[1024];
        int len;
        while((len = bf.read(chs))!=-1){
            bw.write(chs,0,len);
        }

        //释放资源
        bf.close();
        bw.close();
    }
}

10.字符缓冲流特有功能(推荐使用)

11.案例(字符缓冲流特有功能复制Java文件)

代码演示:

代码语言:javascript复制
import java.io.*;

public class CopyJavaDemo2 {
    public static void main(String[] args) throws IOException {
        //创建字符缓冲流对象
        BufferedReader br = new BufferedReader(new FileReader("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP26\StringDemo"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP26\Copy_StringDemo"));

        //读写数据(特有功能)
        String line;
        while((line = br.readLine())!=null){
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        //释放资源
        br.close();
        bw.close();
    }
}


(四)IO流小结



(五)案例

1.集合到文件

代码实现:

代码语言:javascript复制
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

public class ArrayToFile {
    public static void main(String[] args) throws IOException {
        //创建集合对象
        ArrayList<String> array = new ArrayList<>();

        //存储字符串元素
        array.add("hello");
        array.add("java");

        //创建字符缓冲输出流对象
        BufferedWriter br = new BufferedWriter(new FileWriter("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP27\test.txt"));

        //遍历集合,得到每一个字符串数据
        for(String s : array){
            //调用字符缓冲输出流对象的方法写数据
            br.write(s);
            br.newLine();
            br.flush();
        }

        //释放资源
        br.close();

    }
}

2.文件到集合

代码实现:

代码语言:javascript复制
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

public class FileToArrayList {
    public static void main(String[] args) throws IOException {
        //创建字符缓冲输入对象
        BufferedReader br = new BufferedReader(new FileReader("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP27\test.txt"));

        //创建ArrayList集合对象
        ArrayList<String> array = new ArrayList<>();

        //调用字符缓冲输入对象读取数据
        String line;
        while ((line = br.readLine()) != null) {
            array.add(line);
        }

        //释放资源
        br.close();

        //遍历集合
        for (String s : array) {
            System.out.println(s);
        }
    }
}

3.点名器

需求:有一个文件里面存储了班级同学的姓名,每个姓名占一行,要求通过程序实现随机点名器

代码实现:

代码语言:javascript复制
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

public class FileToArrayList {
    public static void main(String[] args) throws IOException {
        //创建字符缓冲输入对象
        BufferedReader br = new BufferedReader(new FileReader("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP27\test.txt"));

        //创建ArrayList集合对象
        ArrayList<String> array = new ArrayList<>();

        //调用字符缓冲输入对象读取数据
        String line;
        while ((line = br.readLine()) != null) {
            array.add(line);
        }

        //释放资源
        br.close();

        //遍历集合
        for (String s : array) {
            System.out.println(s);
        }
    }
}
4.集合到文件(升级版)

把ArrayLIst中的学生数据写入到文本文件中。要求:每一个学生对象的数据作为文件中的一行数据

代码实现:

代码语言:javascript复制
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

public class ArrayToFileProDemo {
    public static void main(String[] args) throws IOException {
        //创建缓冲输出流对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP27\Student.txt"));

        //创建ArrayList集合对象
        ArrayList<Student> array = new ArrayList<>();

        //创建学生对象
        Student s1 = new Student(19103201,"学生1",20,"天津");
        Student s2 = new Student(19103202,"学生2",21,"北京");
        Student s3 = new Student(19103203,"学生3",22,"河北");

        //把学生对象添加到集合中
        array.add(s1);
        array.add(s2);
        array.add(s3);

        //遍历集合得到每一个学生对象
        for(Student s : array){
            String result = getString(s);
            bw.write(result);
            bw.newLine();
            bw.flush();
        }

        //释放资源
        bw.close();
    }


    public static String getString(Student s) {
        StringBuilder sb = new StringBuilder();
        sb.append(s.getSid()).append(", ").append(s.getName()).append(", ").append(s.getAge()).append(", ").append(s.getAddress());

        String ss = sb.toString();

        return ss;
    }
}

5.文件到集合(升级版)

需求:把文本文件中的数据读取到集合中,并遍历集合。要求:文件中每一行数据是一个学生对象的成员变量值

代码实现:

代码语言:javascript复制
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

public class FileToArrayListDemo {
    public static void main(String[] args) throws IOException {
        //创建字符缓冲输出流对象
        BufferedReader br = new BufferedReader(new FileReader("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP27\Student.txt"));

        //创建ArrayList集合
        ArrayList<Student> array = new ArrayList<>();

        //读取数据
        String line;
        while((line = br.readLine())!= null) {
            //将字符串按一定格式分割,得到一个数组
            String[] StrArr = line.split(", ");

            //创建学生对象
            Student s = new Student();
            s.setSid(Integer.parseInt(StrArr[0]));
            s.setName(StrArr[1]);
            s.setAge(Integer.parseInt(StrArr[2]));
            s.setAddress(StrArr[3]);

            //把学生对象添加到集合
            array.add(s);
        }

        //释放资源
        br.close();
        //遍历集合
        for(Student s :array){
            System.out.println(s.getSid() ", " s.getName() ", " s.getAge() ", " s.getAddress());
        }
    }
}

6.集合到文件(数据排序升级版)

需求:键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩)。要求按照成绩总分从高到低写入文本文件

代码语言:javascript复制
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;

public class TreeSetToFile {
    public static void main(String[] args) throws IOException {
        //创建TreeSet集合,通过比较器排序进行排序
        TreeSet<Student1> ts = new TreeSet<>(new Comparator<Student1>() {
            @Override
            public int compare(Student1 s1, Student1 s2) {
                int num = s2.sum() - s1.sum();
                int num2 = num == 0 ? s2.getEnglishScore() - s1.getEnglishScore() : num;
                int num3 = num2 == 0 ? s2.getChineseScore() - s1.getChineseScore() : num2;
                int num4 = num3 == 0 ? s2.getName().compareTo(s1.getName()) : num3;
                return num4;
            }
        });

        for(int i =0;i<3;i  ){
            //键盘录入学生数据
            Scanner sc = new Scanner(System.in);
            System.out.println("请录入第" (i 1) "个学生的信息:");
            System.out.println("请输入学生姓名");
            String name = sc.nextLine();
            System.out.println("请输入学生语文成绩");
            int chineseScore = sc.nextInt();
            System.out.println("请输入学生数学成绩");
            int mathScore = sc.nextInt();
            System.out.println("请输入学生英语成绩");
            int englishSore = sc.nextInt();

            //创建学生对象
            Student1 s = new Student1();
            //将键盘录入的值赋给成员变量
            s.setName(name);
            s.setChineseScore(chineseScore);
            s.setEnglishScore(englishSore);
            s.setMathScore(mathScore);

            //将学生对象添加到集合中
            ts.add(s);
        }

        //创建字符缓冲输出流对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("F:\JAVA\JAVA Document\Review\src\TEMP\TEMP27\Student1.txt"));

        //遍历集合
        for(Student1 s : ts) {
            String ss = getString(s);
            bw.write(ss);
            bw.newLine();
            bw.flush();
        }

        //释放资源
        bw.close();

    }

    //定义获得指定格式字符串的方法
    public static String getString(Student1 s) {
        StringBuilder sb = new StringBuilder();
        sb.append(s.getName()).append(", ").append(s.getChineseScore()).append(", ").append(s.getEnglishScore()).append(", ").append(s.getMathScore()).append(", ").append(s.sum());

        String ss = sb.toString();
        return ss;
    }
}

7.复制单级文件夹

代码实现:

代码语言:javascript复制
import java.io.*;

public class CopyFolderDemo {
    public static void main(String[] args) throws IOException {
        //创建数据源目录
        File srcFolder = new File("F:\testCopyTEMP27");
        //获取数据源目录File对象的名称(TEMP27)
        String srcFolderName = srcFolder.getName();
        //创建目的地目录File对象,路径名是模块名 TEMP27
        File destFolder = new File("src\TEMP",srcFolderName);
        //判断目的地目录对应的File是否存在,如果不存在,就创建
        if(!destFolder.exists()){
            destFolder.mkdir();
        }

        //获取数据源目录下的所有文件的File数组
        File[] listFile = srcFolder.listFiles();
        //遍历数组获得每一个文件
        for(File file : listFile) {
            //获取每个文件的文件名
            String fileSrcName = file.getName();
            //创建目的地文件的File对象
            File destFile = new File(destFolder,fileSrcName);
            //复制文件
            copyFile(file,destFile);
        }
    }

    private static void copyFile(File file, File destFile) throws IOException {
        //创建字节输入输出缓冲流对象
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));

        //读写数据(一次读一个字节数组)
        byte[] bys = new byte[1024];
        int len;
        while((len = bis.read(bys))!=-1){
            bos.write(bys,0,len);
        }

        //释放资源
        bis.close();
        bos.close();
    }
}

8.复制多级文件夹
代码语言:javascript复制
import java.io.*;

public class CopyProDemo {
    public static void main(String[] args) throws IOException {
        //创建数据源对象File
        File srcFile = new File("F:\testCopyTEMP27");
        //创建目的地File对象
        File destFile = new File("src\TEMP");
        //写方法实现文件夹的复制
        copyFolder(srcFile, destFile);
    }

    private static void copyFolder(File srcFile, File destFile) throws IOException {
        //判断数据源File是否为目录
        if (srcFile.isDirectory()) {
            //在目的地创建名字一样的目录
            String srcFileName = srcFile.getName();
            File newDestFolder = new File(destFile, srcFileName);
            if (!newDestFolder.exists()) {//判断是否存在
                //创建新的文件夹
                newDestFolder.mkdir();
            }
            //获取数据源File下的所有文件或者目录的数组
            File[] FileArray = srcFile.listFiles();
            //遍历该数组,获取每一个File对象
            for (File file : FileArray) {
                copyFolder(file, newDestFolder);
            }
        } else {
            //创建一个新的文件名与源文件相同的路径
            File newDestFile = new File(destFile,srcFile.getName());
            copyFile(srcFile,newDestFile);
        }

    }

    private static void copyFile(File file, File destFile) throws IOException {
        //创建字节输入输出缓冲流对象
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));

        //读写数据(一次读一个字节数组)
        byte[] bys = new byte[1024];
        int len;
        while ((len = bis.read(bys)) != -1) {
            bos.write(bys, 0, len);
        }

        //释放资源
        bis.close();
        bos.close();
    }
}

(六)复制文件的异常处理

代码演示:

代码语言:javascript复制
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class ExceptionDemo {
    public static void main(String[] args) {

    }

    //处理异常方法1(直接抛出)
    private static void method1() throws IOException {
        FileReader fr = new FileReader("fr.txt");
        FileWriter fw = new FileWriter("fw.txt");

        char[] chs = new char[1024];
        int len;
        while ((len = fr.read(chs)) != -1) {
            fw.write(chs, 0, len);
        }

        fr.close();
        fw.close();
    }

    //处理异常方法2(正常try...catch..finally标准格式处理异常)
    private static void method2() {
        FileReader fr = null;
        FileWriter fw = null;
        try {
            fr = new FileReader("fr.txt");
            fw = new FileWriter("fw.txt");

            char[] chs = new char[1024];
            int len;
            while ((len = fr.read(chs)) != -1) {
                fw.write(chs, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fr != null) {
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fw != null) {
                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //处理异常方法3(JDK7的改进方案)
    private static void method3() {
        try (FileReader fr = new FileReader("fr.txt");
             FileWriter fw = new FileWriter("fw.txt");){
            char[] chs = new char[1024];
            int len;
            while ((len = fr.read(chs)) != -1) {
                fw.write(chs, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    //处理异常方法4(JDK9的改进方案)
    private static void method4() throws IOException{   //此处相对JDK7来说还要抛出异常
        FileReader fr = new FileReader("fr.txt");
        FileWriter fw = new FileWriter("fw.txt");
        try (fr;fw){ //注意此处是分号;而不是逗号,
            char[] chs = new char[1024];
            int len;
            while ((len = fr.read(chs)) != -1) {
                fw.write(chs, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

(七)特殊操作流

1.标准输入流

System类中有两个静态的成员变量

  • public static final InputStream in:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源
  • public static final PrintStream out:标准输出流。通常该流对应于显示输出或由主机环境或用户指定的另一个输出目标

自己实现键盘录入数据:

  • BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

写起来太麻烦,Java就提供了一个类实现键盘录入

  • Scanner sc = new Scanner(System.in);

代码演示:

代码语言:javascript复制
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Scanner;

public class SystemInDemo {
    public static void main(String[] args) throws IOException {
        /*
        InputStream is = System.in;

        //如何把字节流转换为字符流?用转换流
        InputStreamReader isr = new InputStreamReader(is);
        //如何使用字符流一次读一行数据
        //需要使用字符缓冲输入流的特有方法
        BufferedReader br = new BufferedReader(isr);
         */

        //简化上述三行代码
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("请输入一个字符串:");
        String ss = br.readLine();
        System.out.println("你输入的字符串是:"   ss);
        System.out.println("请输入一个整数:");
        int i = Integer.parseInt(br.readLine());
        System.out.println("你输入的整数为:"   i);
        //这样想要的数据类型代码太麻烦了,所以Java提供了Scanner类来简化代码
        Scanner sc = new Scanner(System.in);
        int i1 = sc.nextInt();
    }
}

(ps:当我学到这里,我感觉我整个人精神了,当这一节出现System.in时我就在想,这个东西跟InputStream什么的乱七八糟的有什么关系???学完了之后真是眼前焕然一新,Scanner 没错就是它,太牛了,绕来绕去又绕回来了,以前刚开始接触Java使用 Scanner键盘录入的时候压根没想过它到底为什么这么写,就觉得键盘录入固定格式就应该这样,随着学习的深入,很多谜团都解开了,原来万物都有个由来。太想记录此刻的心情了哈哈,这些都是我的笔记,在未来我可能会有写博客的习惯,然后将笔记一点点分享到博客中,期待未来我的粉丝们嘿嘿,继续学习了,加油!) (泪目了家人们,上面是一年前刚学Java时傻乎乎的自己记录的感受,今天2022.9.5我也是最近开始了自己的博客创作之旅,能看到这里的不论是路人还是粉丝,谢谢你们的支持,我会继续努力,持续将我的全部Java笔记分享到博客中,以供大家学习参考)


2.标准输出流

public static final PrintStream out:标准输出流。通常该流对应于显示输出或由主机环境或用户指定的另一个输出目标

输出语句的本质:是一个标准的输出流

  • PrintStream ps = System.out;
  • PrintStram类有的方法,System.out都可以使用

注意:其中println方法可以没有参数,但是print方法中必须要传参,因为没有无参的print方法

代码演示:

代码语言:javascript复制
import java.io.PrintStream;

public class SystemOutDemo {
    public static void main(String[] args) {
        PrintStream ps = System.out;
        ps.println("hello");
        ps.println();
        ps.print();//此处报错,因为print方法必须要有参数
        //System.out的本质是一个字节输出流
    }
}

3.打印流

打印流的特点

  • 只负责输出数据,不负责读取数据
  • 有自己的特有方法
(1)字节打印流(PrintStream)
  • PrintStream(String fileName):使用指定的文件名创建新的打印流
  • 使用继承父亲的方法写数据,查看的时候会转码;使用自己的特有方法写数据,查看的数据原样输出

代码演示:

代码语言:javascript复制
import java.io.FileNotFoundException;
import java.io.PrintStream;

public class PrintStreamDemo {
    public static void main(String[] args) throws FileNotFoundException {
        PrintStream ps = new PrintStream("src\TEMP\TEMP28\ps.txt");

        //使用继承父亲的方法
        ps.write(97);//a
        //使用自己特有的方法
        ps.print(97);//97

        ps.println();//换行
        ps.print(98);//98
        ps.println(99);//99
    }
}

(2)字符打印流(PrintWriter)

代码演示:

代码语言:javascript复制
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class PrintWriterDemo {
    public static void main(String[] args) throws IOException {
        //PrintWriter(String FileName)
        PrintWriter pw = new PrintWriter("src\TEMP\TEMP28\pw.txt");
        //继承的方法
        pw.write("hello");
        pw.write("rn");
        pw.flush();
        pw.write("world");
        pw.write("rn");
        pw.flush();

        //特有的方法
        pw.println("hello");
        pw.flush();
        pw.println("world");
        pw.flush();

        //PrintWriter(Writer out,boolean autoFlush)
        PrintWriter pw2 = new PrintWriter(new FileWriter("src\TEMP\TEMP28\pw.txt"),true);
        pw.println("hello");
        pw.println("world");
    }

4.复制Java文件(打印流改进版)
代码语言:javascript复制
import java.io.*;

public class CopyFileDemo {
    public static void main(String[] args) throws IOException {
        //创建输入流对象
        BufferedReader br = new BufferedReader(new FileReader("src\TEMP\TEMP27\Student.txt"));
        //创建输出流对象
        PrintWriter pw = new PrintWriter(new FileWriter("src\TEMP\TEMP28\copyStudent.txt"),true);
        //读写数据,复制文件
        String line;
        while((line = br.readLine())!=null){
            pw.println(line);
        }
        //释放资源
        br.close();
        pw.close();
    }
}

5.对象序列化流

对象序列化流:就是讲对象保存到磁盘中,或者在网路中传输对象

这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的模型、对象的数据和对象中存储的属性等信息

字节序列写到文件之后,相当于文件中持久保存了一个对象的信息

反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化

要实现序列化和反序列化就要使用对象序列化流和对象反序列化流:

  • 对象序列化流:ObjectOutputStream
  • 对象反序列化流:ObjectInputStream
(1)对象序列化流

对象序列化流:ObjectOutputStream

  • 将Java对象的原始数据类型和图形写入OutputStream。可以使用ObjectInputStream读取(重构)对象。可以通过使用流的文件来实现对象的持久存储。如果流是网路套接字流,则可以在另一个主机上或另一个进程中重构对象

构造方法:

  • ObjectOutputStream(OutputStream out):创建一个写入指定的OutStream的ObjectOutputStream

序列化对象的方法:

  • void writeObject(Object obj):将指定的对象写入ObjectOutputStream

注意:

  • 一个对象要想被序列化,该对象所属的类必须实现Serializable接口
  • Serializable是一个标记接口,实现该接口,不需要重写任何方法

代码演示:

代码语言:javascript复制
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class ObjectOutputStreamDemo {
    public static void main(String[] args) throws IOException {
        //ObjectOutputStream(OutputStream out):创建一个写入指定的OutStream的ObjectOutputStream
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("src\TEMP\TEMP28\oos.txt"));
        //创建对象
        Student s = new Student("学生1",20);
        //void writeObject(Object obj):将指定的对象写入ObjectOutputStream
        oos.writeObject(s);
        //释放资源
        oos.close();
    }
}

(2)对象反序列化流

对象反序列化流:ObjectInputStream

  • ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象

构造方法

  • ObjectInputStream(InputStream in):创建从指定的InputStream读取的ObjectInputStream

反序列化对象的方法:

  • Object readObject():从ObjectInputStream读取一个对象

代码演示:

代码语言:javascript复制
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class ObjectInputStreamDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //创建对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("src\TEMP\TEMP28\oos.txt"));
        //读取对象
        Object obj = ois.readObject();
        //向下转型
        Student s = (Student)obj;
        //输出
        System.out.println(s.getName() ", " s.getAge());
        //释放资源
        ois.close();
    }
}
(3)对象序列化的三个问题

6.Properties

Properties概述:(Properties继承了Hashtable,Hashtable与HashMap相似)

  • 是一个Map体系的集合类
  • Properties可以保存到流中或从流中加载

练习:Properties作为Map集合的使用

代码语言:javascript复制
import java.util.Properties;
import java.util.Set;

public class PropertiesDemo {
    public static void main(String[] args) {
        //Properties集合的构造方法中没有泛型<> 所以默认类型都是Object
        Properties prop = new Properties();
        //存储元素
        prop.put("19103200", "学生1");
        prop.put("19103201", "学生2");
        prop.put("19103202", "学生3");
        //遍历集合
        Set<Object> keySet = prop.keySet();
        for (Object key : keySet) {
            Object value = prop.get(key);
            System.out.println(key   ", "   value);
        }
    }
}

Properties集合的特有方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5ICutkkd-1662344106255)(https://cdn.jsdelivr.net/gh/BoBooY-GitHub/JavaSE_imgs@main/imgs/202209012120816.png)]

代码演示:

代码语言:javascript复制
import java.util.Properties;
import java.util.Set;

public class PropertiesDemo2 {
    public static void main(String[] args) {
        Properties prop = new Properties();

        //Object setProperty(String key,String value)
        prop.setProperty("19103200", "学生1");
        prop.setProperty("19103201", "学生2");
        prop.setProperty("19103202", "学生3");

        //Set<String> StringPropertyNames()
        Set<String> names = prop.stringPropertyNames();
        //遍历集合(Properties集合特有的遍历方法)
        for (String key : names) {
            //String getProperty(String key)
            String value = prop.getProperty(key);
            System.out.println(key   ", "   value);
        }
    }
}

7.Properties与IO流结合的方法

代码演示:

代码语言:javascript复制
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;

public class PropertiesDemo3 {
    public static void main(String[] args) throws IOException {
        //把集合中的数据保存到文件
        myStore();
        //把文件中的数据加载到集合
        myLoad();
    }

    private static void myLoad() throws IOException{
        Properties prop = new Properties();
        //void Load(Reader reader)
        FileReader fr = new FileReader("src\TEMP\TEMP28\prop3.txt");
        prop.load(fr);
        fr.close();

        System.out.println(prop);//{19103200=学生1, 19103201=学生2, 19103202=学生3}
    }

    private static void myStore() throws IOException {
        Properties prop = new Properties();
        //存入数据
        prop.setProperty("19103200", "学生1");
        prop.setProperty("19103201", "学生2");
        prop.setProperty("19103202", "学生3");
        //void store(Writer writer,String comments)
        FileWriter fw =new FileWriter("src\TEMP\TEMP28\prop3.txt");
        prop.store(fw,null);//第二个参数为对文件的描述,没有描述则可以写null
        fw.close();
    }
}

8.案例(游戏次数)

需求:请写程序实现猜数字小游戏只能试玩3次,如果还想玩,提示:游戏试玩已结束,想玩请充值(www.BoBooY.com)

代码实现:

创建一个游戏类:

代码语言:javascript复制
import java.util.Random;
import java.util.Scanner;

public class GuessNumber {
    private GuessNumber() {
    }

    public static void start() {
        Random r = new Random();
        int num = r.nextInt(100)   1;
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个数字:");
        while (true) {
            int UserNum = sc.nextInt();
            if (UserNum > num) {
                System.out.println("您输入的数字大了,请重新输入:");
            } else if (UserNum < num) {
                System.out.println("您输入的数字小了,请重新输入:");
            } else if (UserNum == num) {
                System.out.println("猜对了!");
                break;
            }
        }

    }
}

创建游戏测试类:

代码语言:javascript复制
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;

public class PropertiesDemo {
    public static void main(String[] args) throws IOException {
        //创建集合对象
        Properties prop = new Properties();

        //读取文件中的数据
        FileReader fr = new FileReader("smallDemo\src\PropertiesModel\game.txt");
        prop.load(fr);
        //释放资源
        fr.close();
        //获取count键对应的值
        String count = prop.getProperty("count");
        //将String类型转为int类型
        int number = Integer.parseInt(count);
        //判断游戏次数
        if (number >= 3) {
            System.out.println("试玩结束,请充值!");
        } else {
            GuessNumber.start();
            //游戏结束,试玩次数记录加1
            number  ;
            //将int类型数据重新打包为String类型
            prop.setProperty("count",String.valueOf(number));
            //将数据重新写入文件中记录保存
            FileWriter fw = new FileWriter("smallDemo\src\PropertiesModel\game.txt");
            prop.store(fw,null);
            //释放资源
            fw.close();
        }
    }
}

其中已经存在的文件game.txt

代码语言:javascript复制
count = 0

0 人点赞