当前位置:   article > 正文

Java——IO流

Java——IO流

目录

一、IO流的概述

1、IO流的分类

1.1、纯文本文件

2、小结

二、IO流的体系结构

三、字节流

1、FileOutputStream(字节输出流)

2、FileOutputStream写出数据的细节

3、FileOutputStream写数据的3种方式

3.1、一次写一个字节数据

3.2、一次写一个字节数组数据

3.3、一次写一个字节数组的部分数据

4、FileOutputStream写数据的两个小问题

4.1、换行写

4.2、续写

5、小结

6、FileInputStream(字节输入流)

7、FileInputStream书写细节

8、FileInputStream的循环读取

9、文件拷贝

9.1、文件拷贝的基本代码

9.2、文件拷贝的弊端

9.3、文件拷贝弊端的解决方案(一次读多个字节)

9.4、文件拷贝代码改写

10、IO流中不同JDK版本捕获异常的方式

四、字符集

1、ASCII字符集(0-127)

1.1、计算机的存储规则(英文)

2、GBK字符集

2.1、计算机的存储规则(英文)(GBK)

2.2、计算机的存储规则(汉字)(GBK)

3.3、小结

3、Unicode字符集

3.1、UTF-8是一个字符集吗?

3.2、Unicode字符集练习

3.3、小结

五、为什么会有乱码?

1、如何不产生乱码?

2、扩展

3、Java中的编解码方法

六、字符流

1、字符流的体系架构

2、FileReader(字符输入流)

2.1、创建字符输入流对象

2.2、读取数据

2.3、释放资源

3、FileWriter(字符输出流)

3.1、构造方法

3.2、成员方法

3.3、FileWriter书写细节

4、字符输出流写出数据

4.1、write(int c):写出一个字符

4.2、write(String str):写出一个字符串

4.3、write(char[] cbuf):写出一个字符数组

5、字符流原理解析

5.1、字符输入流(FileReader)的原理解析

5.2、字符输出流(FileWriter)的原理解析

七、综合练习

1、字节流和字符流的使用场景

2、练习一:拷贝(字节流)

3、练习二:文件加密

 4、练习三:修改文件中的数据

八、IO流体系中的高级流

1、缓冲流

1.1、字节缓冲流

1.2、字节缓冲流提高效率的原理

1.3、字符缓冲流

1.4、小结

1.5、练习

1.5.1练习一:拷贝文件

1.5.2练习二:修改文本顺序

1.5.3练习三:软件的运行次数

2、转换流(字符流的一种)

2.1、转换流的基本用法

2,2、练习一:转换文件编码

2.3、练习二:读取文件中的数据

2.4、小结

3、序列化流/对象操作输出流(字节流的一种)(ObjectOutputStream)

3.1、构造方法&成员方法

3.2、利用序列化流,把一个对象写到本地文件中

3.3、序列化流的小细节(NotSerializableException)

4、反序列化流/对象操作输入流(ObjectInputStream)

4.1、利用反序列化流/对象操作输入流,把文件中的对象读到程序当中

4.2、序列号不匹配

4.3、瞬态关键字(不会把当前属性序列化到本地文件中)

4.4、小结​编辑

4.5、综合练习:读写多个对象(先写再读)

5、打印流

5.1、字节打印流的构造方法

5.2、字节打印流的成员方法

5.3、占位符扩展

5.4、字符打印流的构造方法

5.5、字符打印流的成员方法

5.6、打印流的应用场景

5.7、小结

6、解压缩流/压缩流​编辑

6.1、解压缩流

6.2、压缩流(压缩单个文件)

6.3、压缩流(压缩文件夹)

7、Commons-io

7.1、Commons-io使用步骤

7.2、Commons-io常见方法

8、Hutool工具包

8.1、IO包的封装类

8.2、FileUtil类

九、综合练习

1、制造假数据

1.1、爬取姓氏

1.2、爬取名字

1.3、数据处理

1.4、数据处理并写出

1.5、利用HuTool包生成假数据

2、随机点名器

2.1、练习1:普通随机点名

2.2、练习2:加入了概率和统计

2.3、练习3:作弊功能

2.4、练习4:随机不能重复,自动开启第二轮​编辑

2.5、练习5:带权重的随机​编辑

3、登录注册

3.1、练习1:写一个登录小案例

3.2、练习2:添加锁定账号功能

3.3、练习3:补全拼图小游戏的登录注册(考虑多个用户)

4、游戏的存档和读档

4.1、存档

4.2、读档​编辑

4.3、修改bug

5、游戏配置

5.1、配置文件的优点

5.2、常见的配置文件

5.3、properties配置文件

5.4、Properties作为Map集合的操作

5.5、Properties跟IO流结合的操作(store)

5.6、读取Properties(load)

5.7、拼图游戏的配置文件

4、每日一记(IO的最终大作业)​编辑


一、IO流的概述

IO流:存储和读取数据的解决方案

IO流和File是息息相关的 

 

1、IO流的分类

1.1、纯文本文件

word、Excel不是纯文本文件

而txt或者md文件是纯文本文件

2、小结

二、IO流的体系结构

三、字节流

1、FileOutputStream(字节输出流)

代码

结果

2、FileOutputStream写出数据的细节

 

3、FileOutputStream写数据的3种方式

 

3.1、一次写一个字节数据

3.2、一次写一个字节数组数据

3.3、一次写一个字节数组的部分数据

 

4、FileOutputStream写数据的两个小问题

4.1、换行写

 

4.2、续写

5、小结

6、FileInputStream(字节输入流)

 示例代码

7、FileInputStream书写细节

 

8、FileInputStream的循环读取

 

细节误区:

9、文件拷贝

9.1、文件拷贝的基本代码

 课堂练习:要求统计一下拷贝时间,单位毫秒 

 

9.2、文件拷贝的弊端

9.3、文件拷贝弊端的解决方案(一次读多个字节)

示例代码:

改进方法:

9.4、文件拷贝代码改写

10、IO流中不同JDK版本捕获异常的方式

示例代码

简化方案:(了解即可)

代码实现:(但在实际开发中几乎所有的异常都是抛出处理的) 

JDK7

JDK9

四、字符集

1、ASCII字符集(0-127)

1.1、计算机的存储规则(英文)

编码:

解码:

2、GBK字符集

主要掌握

2.1、计算机的存储规则(英文)(GBK)

2.2、计算机的存储规则(汉字)(GBK)

高位字节二进制一定以1开头,是为了和英文做出区分

解码:(直接转成十进制即可)

3.3、小结

核心1: GBK中,一个英文字母一个字节,二进制第一位是0
核心2: GBK中,一个中文汉字两个字节,二进制第一位是1

3、Unicode字符集

 为了减少浪费,那么就有了UTF-8编码规则:

 

 

3.1、UTF-8是一个字符集吗?

 不是,UTF-8只是Unicode字符集的一种编码方式

3.2、Unicode字符集练习

 

3.3、小结

五、为什么会有乱码?

 

1、如何不产生乱码?

2、扩展

因为拷贝的时候是一个字节一个字节拷贝的,数据没有出现丢失,那么只要记事本打开的字符集和编码方式也和数据源保持一致,就不会出现乱码。 

3、Java中的编解码方法

六、字符流

1、字符流的体系架构

2、FileReader(字符输入流)

2.1、创建字符输入流对象

  1. //1.创建对象并关联本地文件
  2. FileReader fr = new FileReader("myio\\a.txt");

2.2、读取数据

 示例代码:(空参的read方法)

 

示例代码(带参的read方法)

//read(chars):读取数据,解码,强转三步合并了,把强转之后的字符放到数组当中
//空参的read + 强转类型转换

2.3、释放资源

 示例代码:

3、FileWriter(字符输出流)

3.1、构造方法

3.2、成员方法

3.3、FileWriter书写细节

4、字符输出流写出数据

4.1、write(int c):写出一个字符

示例代码:(字节流,每次只能操作一个字节)

4.2、write(String str):写出一个字符串

4.3、write(char[] cbuf):写出一个字符数组

5、字符流原理解析

5.1、字符输入流(FileReader)的原理解析

示例代码:(底层揭秘)

Ⅰ、创建字符输入流对象

Ⅱ、读取数据

扩展:

5.2、字符输出流(FileWriter)的原理解析

数据会先写到缓冲区中

 示例代码:(当出现字节数组装满了、被刷新、被关闭三种任意一种时,字节数组中的数据都会被写入到文件当中)

七、综合练习

1、字节流和字符流的使用场景

2、练习一:拷贝(字节流)

  1. import java.io.File;
  2. import java.io.FileInputStream;
  3. import java.io.FileOutputStream;
  4. import java.io.IOException;
  5. public class Test01 {
  6. public static void main(String[] args) throws IOException {
  7. //拷贝一个文件夹,考虑子文件夹
  8. //1.创建对象表示数据源
  9. File src = new File("D:\\aaa\\src");
  10. //2.创建对象表示目的地
  11. File dest = new File("D:\\aaa\\dest");
  12. //3.调用方法开始拷贝
  13. copydir(src,dest);
  14. }
  15. /*
  16. * 作用:拷贝文件夹
  17. * 参数一:数据源
  18. * 参数二:目的地
  19. *
  20. * */
  21. private static void copydir(File src, File dest) throws IOException {
  22. dest.mkdirs();
  23. //递归
  24. //1.进入数据源
  25. File[] files = src.listFiles();
  26. //2.遍历数组
  27. for (File file : files) {
  28. if(file.isFile()){
  29. //3.判断文件,拷贝
  30. FileInputStream fis = new FileInputStream(file);
  31. FileOutputStream fos = new FileOutputStream(new File(dest,file.getName()));
  32. byte[] bytes = new byte[1024];
  33. int len;
  34. while((len = fis.read(bytes)) != -1){
  35. fos.write(bytes,0,len);
  36. }
  37. fos.close();
  38. fis.close();
  39. }else {
  40. //4.判断文件夹,递归
  41. copydir(file, new File(dest,file.getName()));
  42. }
  43. }
  44. }
  45. }

3、练习二:文件加密

 小知识:如果一个数字它异或另外一个数字两次,那么它得到的数字就是它本身

^ : 异或
    两边相同:false
    两边不同:true

加密:

 

解密:

 4、练习三:修改文件中的数据

细节1:
     文件中的数据不要换行

 细节2:
     bom头

在utf-8编码文件中BOM在文件头部,占用三个字节,用来标示该文件属于utf-8编码。其实UTF-8 的BOM对UFT-8没有作用,是为了支援UTF-16,UTF-32才加上的BOM,BOM签名的意思就是告诉编辑器当前文件采用何种编码,方便编辑器识别,但是BOM虽然在编辑器中不显示,但是会产生输出,就像多了一个空行。

示例代码:(常规写法)

  1. //1.读取数据
  2. FileReader fr = new FileReader("myio\\a.txt");
  3. StringBuilder sb = new StringBuilder();
  4. int ch;
  5. while((ch = fr.read()) != -1){
  6. sb.append((char)ch);
  7. }
  8. fr.close();
  9. System.out.println(sb);
  10. //2.排序
  11. String str = sb.toString();
  12. String[] arrStr = str.split("-");//2-1-9-4-7-8
  13. ArrayList<Integer> list = new ArrayList<>();
  14. for (String s : arrStr) {
  15. int i = Integer.parseInt(s);
  16. list.add(i);
  17. }
  18. Collections.sort(list);
  19. System.out.println(list);
  20. //3.写出
  21. FileWriter fw = new FileWriter("myio\\a.txt");
  22. for (int i = 0; i < list.size(); i++) {
  23. if(i == list.size() - 1){
  24. fw.write(list.get(i) + "");
  25. }else{
  26. fw.write(list.get(i) + "-");
  27. }
  28. }
  29. fw.close();

 示例代码:(非常规写法—Stream && 方法引用)

  1. //1.读取数据
  2. FileReader fr = new FileReader("myio\\a.txt");
  3. StringBuilder sb = new StringBuilder();
  4. int ch;
  5. while((ch = fr.read()) != -1){
  6. sb.append((char)ch);
  7. }
  8. fr.close();
  9. System.out.println(sb);
  10. //2.排序
  11. Integer[] arr = Arrays.stream(sb.toString()
  12. .split("-"))
  13. .map(Integer::parseInt)
  14. .sorted()
  15. .toArray(Integer[]::new);
  16. //3.写出
  17. FileWriter fw = new FileWriter("myio\\a.txt");
  18. String s = Arrays.toString(arr).replace(", ","-");
  19. String result = s.substring(1, s.length() - 1);
  20. fw.write(result);
  21. fw.close();

八、IO流体系中的高级流

1、缓冲流

1.1、字节缓冲流

缓冲流是一个高级流,是对基本流的一个包装 

利用字节缓冲流拷贝文件:(示例代码) 

需求:
*       利用字节缓冲流拷贝文件
*
*   字节缓冲输入流的构造方法:
*           public BufferedInputStream(InputStream is)
*
*    字节缓冲输出流的构造方法:
*           public BufferedOutputStream(OutputStream os)

 默认缓冲区都是8192,基本流的关闭在底层会自动执行

  1. //1.创建缓冲流的对象
  2. BufferedInputStream bis = new BufferedInputStream(new FileInputStream("myio\\a.txt"));
  3. BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myio\\a.txt"));
  4. //2.循环读取并写到目的地
  5. int b;
  6. while ((b = bis.read()) != -1) {
  7. bos.write(b);
  8. }
  9. //3.释放资源
  10. bos.close();
  11. bis.close();

利用字节缓冲流拷贝文件:(一次读写多个字节) 

  1. //1.创建缓冲流的对象
  2. BufferedInputStream bis = new BufferedInputStream(new FileInputStream("myio\\a.txt"));
  3. BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myio\\copy2.txt"));
  4. //2.拷贝(一次读写多个字节)
  5. byte[] bytes = new byte[1024];
  6. int len;
  7. while((len = bis.read(bytes)) != -1){
  8. bos.write(bytes,0,len);
  9. }
  10. //3.释放资源
  11. bos.close();
  12. bis.close();

1.2、字节缓冲流提高效率的原理

倒手的过程是在内存中发生的,而内存的速度是非常快的,几乎可以忽略不计

它真正节约的是读和写的时候跟硬盘之间打交道的时间,其根本原因是因为字节流默认不使用缓冲区;切勿与字符流搞混

1.3、字符缓冲流

 但是因为字符流本身就带有缓冲区,所以字符缓冲流对效率的提升就不是很明显。

构造方法:

特有方法:

  1. package com.yaqi.mybufferedstream1;
  2. import java.io.BufferedReader;
  3. import java.io.FileReader;
  4. import java.io.IOException;
  5. public class BufferedStreamDemo3 {
  6. public static void main(String[] args) throws IOException {
  7. /*
  8. * 字符缓冲输入流:
  9. * 构造方法:
  10. * public BufferedReader(Reader r)
  11. * 特有方法:
  12. * public String readLine() 读一整行
  13. *
  14. * */
  15. //1.创建字符缓冲输入流的对象
  16. BufferedReader br = new BufferedReader(new FileReader("myio\\a.txt"));
  17. //2.读取数据
  18. //细节:
  19. //readLine方法在读取的时候,一次读一整行,遇到回车换行结束
  20. // 但是他不会把回车换行读到内存当中
  21. /* String line1 = br.readLine();
  22. System.out.println(line1);
  23. String line2 = br.readLine();
  24. System.out.println(line2);*/
  25. String line;
  26. while ((( line = br.readLine()) != null)){
  27. System.out.println(line);
  28. }
  29. //3.释放资源
  30. br.close();
  31. }
  32. }

1.4、小结

1.5、练习

1.5.1练习一:拷贝文件

  1. package com.yaqi.mytest;
  2. import java.io.*;
  3. public class Test05 {
  4. public static void main(String[] args) throws IOException {
  5. /*
  6. 四种方式拷贝文件,并统计各自用时
  7. */
  8. long start = System.currentTimeMillis();
  9. //method1();
  10. //method2(); //16.253秒
  11. //method3(); //95.466秒
  12. //method4(); //17.686秒
  13. long end = System.currentTimeMillis();
  14. System.out.println((end - start) / 1000.0 + "秒");
  15. }
  16. //字节流的基本流:一次读写一个字节4,588,568,576 字节
  17. public static void method1() throws IOException {
  18. FileInputStream fis = new FileInputStream("E:\\aaa\\CentOS-7-x86_64-DVD-1810.iso");
  19. FileOutputStream fos = new FileOutputStream("myio\\copy.iso");
  20. int b;
  21. while ((b = fis.read()) != -1) {
  22. fos.write(b);
  23. }
  24. fos.close();
  25. fis.close();
  26. }
  27. //字节流的基本流:一次读写一个字节数组
  28. public static void method2() throws IOException {
  29. FileInputStream fis = new FileInputStream("E:\\aaa\\CentOS-7-x86_64-DVD-1810.iso");
  30. FileOutputStream fos = new FileOutputStream("myio\\copy.iso");
  31. byte[] bytes = new byte[8192];
  32. int len;
  33. while ((len = fis.read(bytes)) != -1) {
  34. fos.write(bytes, 0, len);
  35. }
  36. fos.close();
  37. fis.close();
  38. }
  39. //字节流的基本流:一次读写一个字节数组
  40. public static void method3() throws IOException {
  41. BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E:\\aaa\\CentOS-7-x86_64-DVD-1810.iso"));
  42. BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myio\\copy.iso"));
  43. int b;
  44. while ((b = bis.read()) != -1) {
  45. bos.write(b);
  46. }
  47. bos.close();
  48. bis.close();
  49. }
  50. //字节流的基本流:一次读写一个字节数组
  51. public static void method4() throws IOException {
  52. BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E:\\aaa\\CentOS-7-x86_64-DVD-1810.iso"));
  53. BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myio\\copy.iso"));
  54. byte[] bytes = new byte[8192];
  55. int len;
  56. while ((len = bis.read(bytes)) != -1) {
  57. bos.write(bytes, 0, len);
  58. }
  59. bos.close();
  60. bis.close();
  61. }
  62. }

1.5.2练习二:修改文本顺序

 示例代码:(Collections排序)

示例代码:(TreeMap排序)

 

1.5.3练习三:软件的运行次数
实现一个验证程序运行次数的小程序,要求如下:
1.当程序运行超过3次时给出提示:本软件只能免费使用3次,欢迎您注册会员后继续使用~
2.程序运行演示如下:
    第一次运行控制台输出: 欢迎使用本软件,第1次使用免费~
    第二次运行控制台输出: 欢迎使用本软件,第2次使用免费~
    第三次运行控制台输出: 欢迎使用本软件,第3次使用免费~
    第四次及之后运行控制台输出:本软件只能免费使用3次,欢迎您注册会员后继续使用~

//原则:
//IO:随用随创建
//    什么时候不用什么时候关闭

2、转换流(字符流的一种)

转换流是字符流和字节流之间的桥梁

2.1、转换流的基本用法

 指定字符集读取:

  1. package com.yaqi.myconvertstream;
  2. import java.io.*;
  3. import java.nio.charset.Charset;
  4. public class ConvertStreamDemo1 {
  5. public static void main(String[] args) throws IOException {
  6. /*
  7. 利用转换流按照指定字符编码读取(了解)
  8. 因为JDK11:这种方式被淘汰了。替代方案(掌握)
  9. F:\JavaSE最新版\day29-IO(其他流)\资料\gbkfile.txt
  10. */
  11. /* //1.创建对象并指定字符编码
  12. InputStreamReader isr = new InputStreamReader(new FileInputStream("myio\\gbkfile.txt"),"GBK");
  13. //2.读取数据
  14. int ch;
  15. while ((ch = isr.read()) != -1){
  16. System.out.print((char)ch);
  17. }
  18. //3.释放资源
  19. isr.close();*/
  20. FileReader fr = new FileReader("myio\\gbkfile.txt", Charset.forName("GBK"));
  21. //2.读取数据
  22. int ch;
  23. while ((ch = fr.read()) != -1){
  24. System.out.print((char)ch);
  25. }
  26. //3.释放资源
  27. fr.close();
  28. }
  29. }

利用转换流按照指定字符编码写出数据: 

  1. import java.io.*;
  2. import java.nio.charset.Charset;
  3. public class ConvertStreamDemo2 {
  4. public static void main(String[] args) throws IOException {
  5. /*
  6. 利用转换流按照指定字符编码写出
  7. */
  8. /*
  9. //1.创建转换流的对象
  10. OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myio\\b.txt"),"GBK");
  11. //2.写出数据
  12. osw.write("你好你好");
  13. //3.释放资源
  14. osw.close();*/
  15. FileWriter fw = new FileWriter("myio\\c.txt", Charset.forName("GBK"));
  16. fw.write("你好你好");
  17. fw.close();
  18. }
  19. }

2,2、练习一:转换文件编码

将本地文件中的GBK文件,转成UTF-8 

  1. package com.yaqi.myconvertstream;
  2. import java.io.*;
  3. import java.nio.charset.Charset;
  4. public class ConvertStreamDemo3 {
  5. public static void main(String[] args) throws IOException {
  6. /*
  7. 将本地文件中的GBK文件,转成UTF-8
  8. */
  9. //1.JDK11以前的方案
  10. /* InputStreamReader isr = new InputStreamReader(new FileInputStream("myio\\b.txt"),"GBK");
  11. OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myio\\d.txt"),"UTF-8");
  12. int b;
  13. while((b = isr.read()) != -1){
  14. osw.write(b);
  15. }
  16. osw.close();
  17. isr.close();*/
  18. //2.替代方案
  19. FileReader fr = new FileReader("myio\\b.txt", Charset.forName("GBK"));
  20. FileWriter fw = new FileWriter("myio\\e.txt",Charset.forName("UTF-8"));
  21. int b;
  22. while ((b = fr.read()) != -1){
  23. fw.write(b);
  24. }
  25. fw.close();
  26. fr.close();
  27. }
  28. }

2.3、练习二:读取文件中的数据

  1. package com.yaqi.myconvertstream;
  2. import java.io.*;
  3. public class ConvertStreamDemo4 {
  4. public static void main(String[] args) throws IOException {
  5. /*
  6. 利用字节流读取文件中的数据,每次读一整行,而且不能出现乱码
  7. //1.字节流在读取中文的时候,是会出现乱码的,但是字符流可以搞定
  8. //2.字节流里面是没有读一整行的方法的,只有字符缓冲流才能搞定
  9. */
  10. /* FileInputStream fis = new FileInputStream("myio\\a.txt");
  11. InputStreamReader isr = new InputStreamReader(fis);
  12. BufferedReader br = new BufferedReader(isr);
  13. String str = br.readLine();
  14. System.out.println(str);
  15. br.close();*/
  16. BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("myio\\a.txt")));
  17. String line;
  18. while ((line = br.readLine()) != null){
  19. System.out.println(line);
  20. }
  21. br.close();
  22. }
  23. }

2.4、小结

3、序列化流/对象操作输出流(字节流的一种)(ObjectOutputStream)

3.1、构造方法&成员方法

3.2、利用序列化流,把一个对象写到本地文件中

  1. import java.io.FileOutputStream;
  2. import java.io.IOException;
  3. import java.io.ObjectOutputStream;
  4. public class ObjectStreamDemo1 {
  5. public static void main(String[] args) throws IOException {
  6. /*
  7. 需求:
  8. 利用序列化流/对象操作输出流,把一个对象写到本地文件中
  9. 构造方法:
  10. public ObjectOutputStream(OutputStream out) 把基本流变成高级流
  11. 成员方法:
  12. public final void writeObject(Object obj) 把对象序列化(写出)到文件中去
  13. */
  14. //1.创建对象
  15. Student stu = new Student("zhangsan",23,"南京");
  16. //2.创建序列化流的对象/对象操作输出流
  17. ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myio\\a.txt"));
  18. //3.写出数据
  19. oos.writeObject(stu);
  20. //4.释放资源
  21. oos.close();
  22. }
  23. }

3.3、序列化流的小细节(NotSerializableException)

4、反序列化流/对象操作输入流(ObjectInputStream)

4.1、利用反序列化流/对象操作输入流,把文件中的对象读到程序当中

4.2、序列号不匹配

如果一个类实现了序列化接口Serializable,那么就表示这个类的对象是可被序列化的

解决方案:固定版本号

方法一: 手动书写

方法二:设置Idea,让其自动书写

Settings -> 搜索Serializable -> 勾选下方两个选项 -> Apply

方法三:搜索Java中已经写好的一个类,如ArrayList,然后复制它的 

4.3、瞬态关键字(不会把当前属性序列化到本地文件中)

如果你在JavaBean中有哪个属性是不想让它进行序列化,就给它加上transient关键字

 

4.4、小结

4.5、综合练习:读写多个对象(先写再读)

序列化多个对象:

反序列化:

5、打印流

5.1、字节打印流的构造方法

5.2、字节打印流的成员方法

示例代码:

5.3、占位符扩展

  1. import java.io.FileNotFoundException;
  2. import java.io.PrintStream;
  3. import java.util.Date;
  4. public class PrintStreamDemo2 {
  5. public static void main(String[] args) throws FileNotFoundException {
  6. PrintStream ps = new PrintStream("a.txt");
  7. //% n表示换行
  8. ps.printf("我叫%s %n", "阿玮");
  9. ps.printf("%s喜欢%s %n", "阿珍", "阿强");
  10. ps.printf("字母H的大写:%c %n", 'H');
  11. ps.printf("8>3的结果是:%b %n", 8 > 3);
  12. ps.printf("100的一半是:%d %n", 100 / 2);
  13. ps.printf("100的16进制数是:%x %n", 100);
  14. ps.printf("100的8进制数是:%o %n", 100);
  15. ps.printf("50元的书打8.5折扣是:%f元%n", 50 * 0.85);
  16. ps.printf("计算的结果转16进制:%a %n", 50 * 0.85);
  17. ps.printf("计算的结果转科学计数法表示:%e %n", 50 * 0.85);
  18. ps.printf("计算的结果转成指数和浮点数,结果的长度较短的是:%g %n", 50 * 0.85);
  19. ps.printf("带有百分号的符号表示法,以百分之85为例:%d%% %n", 85);
  20. ps.println("---------------------");
  21. double num1 = 1.0;
  22. ps.printf("num: %.4g %n", num1);
  23. ps.printf("num: %.5g %n", num1);
  24. ps.printf("num: %.6g %n", num1);
  25. float num2 = 1.0F;
  26. ps.printf("num: %.4f %n", num2);
  27. ps.printf("num: %.5f %n", num2);
  28. ps.printf("num: %.6f %n", num2);
  29. ps.println("---------------------");
  30. ps.printf("数字前面带有0的表示方式:%03d %n", 7);
  31. ps.printf("数字前面带有0的表示方式:%04d %n", 7);
  32. ps.printf("数字前面带有空格的表示方式:% 8d %n", 7);
  33. ps.printf("整数分组的效果是:%,d %n", 9989997);
  34. ps.println("---------------------");
  35. //最终结果是10位,小数点后面是5位,不够在前面补空格,补满10位
  36. //如果实际数字小数点后面过长,但是只规定两位,会四舍五入
  37. //如果整数部分过长,超出规定的总长度,会以实际为准
  38. ps.printf("一本书的价格是:%2.5f元%n", 49.8);
  39. ps.printf("%(f%n", -76.04);
  40. //%f,默认小数点后面7位,
  41. //<,表示采取跟前面一样的内容
  42. ps.printf("%f和%3.2f %n", 86.04, 1.789651);
  43. ps.printf("%f和%<3.2f %n", 86.04, 1.789651);
  44. ps.println("---------------------");
  45. Date date = new Date();
  46. // %t 表示时间,但是不能单独出现,要指定时间的格式
  47. // %tc 周二 12月 06 22:08:40 CST 2022
  48. // %tD 斜线隔开
  49. // %tF 冒号隔开(12小时制)
  50. // %tr 冒号隔开(24小时制)
  51. // %tT 冒号隔开(24小时制,带时分秒)
  52. ps.printf("全部日期和时间信息:%tc %n", date);
  53. ps.printf("月/日/年格式:%tD %n", date);
  54. ps.printf("年-月-日格式:%tF %n", date);
  55. ps.printf("HH:MM:SS PM格式(12时制):%tr %n", date);
  56. ps.printf("HH:MM格式(24时制):%tR %n", date);
  57. ps.printf("HH:MM:SS格式(24时制):%tT %n", date);
  58. System.out.println("---------------------");
  59. ps.printf("星期的简称:%ta %n", date);
  60. ps.printf("星期的全称:%tA %n", date);
  61. ps.printf("英文月份简称:%tb %n", date);
  62. ps.printf("英文月份全称:%tB %n", date);
  63. ps.printf("年的前两位数字(不足两位前面补0):%tC %n", date);
  64. ps.printf("年的后两位数字(不足两位前面补0):%ty %n", date);
  65. ps.printf("一年中的第几天:%tj %n", date);
  66. ps.printf("两位数字的月份(不足两位前面补0):%tm %n", date);
  67. ps.printf("两位数字的日(不足两位前面补0):%td %n", date);
  68. ps.printf("月份的日(前面不补0):%te %n", date);
  69. System.out.println("---------------------");
  70. ps.printf("两位数字24时制的小时(不足2位前面补0):%tH %n", date);
  71. ps.printf("两位数字12时制的小时(不足2位前面补0):%tI %n", date);
  72. ps.printf("两位数字24时制的小时(前面不补0):%tk %n", date);
  73. ps.printf("两位数字12时制的小时(前面不补0):%tl %n", date);
  74. ps.printf("两位数字的分钟(不足2位前面补0):%tM %n", date);
  75. ps.printf("两位数字的秒(不足2位前面补0):%tS %n", date);
  76. ps.printf("三位数字的毫秒(不足3位前面补0):%tL %n", date);
  77. ps.printf("九位数字的毫秒数(不足9位前面补0):%tN %n", date);
  78. ps.printf("小写字母的上午或下午标记(英):%tp %n", date);
  79. ps.printf("小写字母的上午或下午标记(中):%tp %n", date);
  80. ps.printf("相对于GMT的偏移量:%tz %n", date);
  81. ps.printf("时区缩写字符串:%tZ%n", date);
  82. ps.printf("1970-1-1 00:00:00 到现在所经过的秒数:%ts %n", date);
  83. ps.printf("1970-1-1 00:00:00 到现在所经过的毫秒数:%tQ %n", date);
  84. ps.close();
  85. }
  86. }
我叫阿玮 
阿珍喜欢阿强 
字母H的大写:H 
8>3的结果是:true 
100的一半是:50 
100的16进制数是:64 
100的8进制数是:144 
50元的书打8.5折扣是:42.500000元
计算的结果转16进制:0x1.54p5 
计算的结果转科学计数法表示:4.250000e+01 
计算的结果转成指数和浮点数,结果的长度较短的是:42.5000 
带有百分号的符号表示法,以百分之85为例:85% 
---------------------
num: 1.000 
num: 1.0000 
num: 1.00000 
num: 1.0000 
num: 1.00000 
num: 1.000000 
---------------------
数字前面带有0的表示方式:007 
数字前面带有0的表示方式:0007 
数字前面带有空格的表示方式:       7 
整数分组的效果是:9,989,997 
---------------------
一本书的价格是:49.80000元
(76.040000)
86.040000和1.79 
86.040000和86.04 
---------------------
全部日期和时间信息:周六 2月 17 11:14:21 CST 2024 
月/日/年格式:02/17/24 
年-月-日格式:2024-02-17 
HH:MM:SS PM格式(12时制):11:14:21 上午 
HH:MM格式(24时制):11:14 
HH:MM:SS格式(24时制):11:14:21 
星期的简称:周六 
星期的全称:星期六 
英文月份简称:2月 
英文月份全称:二月 
年的前两位数字(不足两位前面补0):20 
年的后两位数字(不足两位前面补0):24 
一年中的第几天:048 
两位数字的月份(不足两位前面补0):02 
两位数字的日(不足两位前面补0):17 
月份的日(前面不补0):17  
两位数字24时制的小时(不足2位前面补0):11 
两位数字12时制的小时(不足2位前面补0):11 
两位数字24时制的小时(前面不补0):11 
两位数字12时制的小时(前面不补0):11 
两位数字的分钟(不足2位前面补0):14 
两位数字的秒(不足2位前面补0):21 
三位数字的毫秒(不足3位前面补0):160 
九位数字的毫秒数(不足9位前面补0):160000000 
小写字母的上午或下午标记(英):上午 
小写字母的上午或下午标记(中):上午 
相对于GMT的偏移量:+0800 
时区缩写字符串:CST
1970-1-1 00:00:00 到现在所经过的秒数:1708139661 
1970-1-1 00:00:00 到现在所经过的毫秒数:1708139661160 

5.4、字符打印流的构造方法

5.5、字符打印流的成员方法

 示例代码:

5.6、打印流的应用场景

5.7、小结

6、解压缩流/压缩流

6.1、解压缩流

  1. import java.io.File;
  2. import java.io.FileInputStream;
  3. import java.io.FileOutputStream;
  4. import java.io.IOException;
  5. import java.util.zip.ZipEntry;
  6. import java.util.zip.ZipInputStream;
  7. /*
  8. * 解压缩流
  9. *
  10. * */
  11. public class ZipStreamDemo1 {
  12. public static void main(String[] args) throws IOException {
  13. //1.创建一个File表示要解压的压缩包
  14. File src = new File("D:\\aaa.zip");
  15. //2.创建一个File表示解压的目的地
  16. File dest = new File("D:\\");
  17. //调用方法
  18. unzip(src,dest);
  19. }
  20. //定义一个方法用来解压
  21. public static void unzip(File src,File dest) throws IOException {
  22. //解压的本质:把压缩包里面的每一个文件或者文件夹读取出来,按照层级拷贝到目的地当中
  23. //创建一个解压缩流用来读取压缩包中的数据
  24. ZipInputStream zip = new ZipInputStream(new FileInputStream(src));
  25. //要先获取到压缩包里面的每一个zipentry对象
  26. //表示当前在压缩包中获取到的文件或者文件夹
  27. ZipEntry entry;
  28. while((entry = zip.getNextEntry()) != null){
  29. System.out.println(entry);
  30. if(entry.isDirectory()){
  31. //文件夹:需要在目的地dest处创建一个同样的文件夹
  32. File file = new File(dest,entry.toString());
  33. file.mkdirs();
  34. }else{
  35. //文件:需要读取到压缩包中的文件,并把他存放到目的地dest文件夹中(按照层级目录进行存放)
  36. FileOutputStream fos = new FileOutputStream(new File(dest,entry.toString()));
  37. int b;
  38. while((b = zip.read()) != -1){
  39. //写到目的地
  40. fos.write(b);
  41. }
  42. fos.close();
  43. //表示在压缩包中的一个文件处理完毕了。
  44. zip.closeEntry();
  45. }
  46. }
  47. zip.close();
  48. }
  49. }

6.2、压缩流(压缩单个文件)

  1. package com.yaqi.myzipstream;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.util.zip.ZipEntry;
  7. import java.util.zip.ZipOutputStream;
  8. public class ZipStreamDemo2 {
  9. public static void main(String[] args) throws IOException {
  10. /*
  11. * 压缩流
  12. * 需求:
  13. * 把D:\\a.txt打包成一个压缩包
  14. * */
  15. //1.创建File对象表示要压缩的文件
  16. File src = new File("D:\\a.txt");
  17. //2.创建File对象表示压缩包的位置
  18. File dest = new File("D:\\");
  19. //3.调用方法用来压缩
  20. toZip(src,dest);
  21. }
  22. /*
  23. * 作用:压缩
  24. * 参数一:表示要压缩的文件
  25. * 参数二:表示压缩包的位置
  26. * */
  27. public static void toZip(File src,File dest) throws IOException {
  28. //1.创建压缩流关联压缩包
  29. ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(new File(dest,"a.zip")));
  30. //2.创建ZipEntry对象,表示压缩包里面的每一个文件和文件夹
  31. //参数:压缩包里面的路径
  32. ZipEntry entry = new ZipEntry("aaa\\bbb\\a.txt");
  33. //3.把ZipEntry对象放到压缩包当中
  34. zos.putNextEntry(entry);
  35. //4.把src文件中的数据写到压缩包当中
  36. FileInputStream fis = new FileInputStream(src);
  37. int b;
  38. while((b = fis.read()) != -1){
  39. zos.write(b);
  40. }
  41. zos.closeEntry();
  42. zos.close();
  43. }
  44. }

6.3、压缩流(压缩文件夹)

  1. package com.yaqi.myzipstream;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.util.zip.ZipEntry;
  7. import java.util.zip.ZipOutputStream;
  8. public class ZipStreamDemo3 {
  9. public static void main(String[] args) throws IOException {
  10. /*
  11. * 压缩流
  12. * 需求:
  13. * 把D:\\aaa文件夹压缩成一个压缩包
  14. * */
  15. //1.创建File对象表示要压缩的文件夹
  16. File src = new File("D:\\aaa");
  17. //2.创建File对象表示压缩包放在哪里(压缩包的父级路径)
  18. File destParent = src.getParentFile();//D:\\
  19. //3.创建File对象表示压缩包的路径
  20. File dest = new File(destParent,src.getName() + ".zip");
  21. //4.创建压缩流关联压缩包
  22. ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(dest));
  23. //5.获取src里面的每一个文件,变成ZipEntry对象,放入到压缩包当中
  24. toZip(src,zos,src.getName());//aaa
  25. //6.释放资源
  26. zos.close();
  27. }
  28. /*
  29. * 作用:获取src里面的每一个文件,变成ZipEntry对象,放入到压缩包当中
  30. * 参数一:数据源
  31. * 参数二:压缩流
  32. * 参数三:压缩包内部的路径
  33. * */
  34. public static void toZip(File src,ZipOutputStream zos,String name) throws IOException {
  35. //1.进入src文件夹
  36. File[] files = src.listFiles();
  37. //2.遍历数组
  38. for (File file : files) {
  39. if(file.isFile()){
  40. //3.判断-文件,变成ZipEntry对象,放入到压缩包当中
  41. ZipEntry entry = new ZipEntry(name + "\\" + file.getName());//aaa\\no1\\a.txt
  42. zos.putNextEntry(entry);
  43. //读取文件中的数据,写到压缩包
  44. FileInputStream fis = new FileInputStream(file);
  45. int b;
  46. while((b = fis.read()) != -1){
  47. zos.write(b);
  48. }
  49. fis.close();
  50. zos.closeEntry();
  51. }else{
  52. //4.判断-文件夹,递归
  53. toZip(file,zos,name + "\\" + file.getName());
  54. // no1 aaa \\ no1
  55. }
  56. }
  57. }
  58. }

7、Commons-io

7.1、Commons-io使用步骤

7.2、Commons-io常见方法

  1. //复制文件
  2. File src = new File("myio\\a.txt");
  3. File dest = new File("myio\\copy.txt");
  4. FileUtils.copyFile(src,dest);

  1. //复制文件夹
  2. File src = new File("D:\\aaa");
  3. File dest = new File("D:\\bbb");
  4. FileUtils.copyDirectoryToDirectory(src,dest);

 ToDirectory:相当于把源文件夹原封不动的拷贝到dest文件夹里面

FileUtils.copyDirectoryToDirectory(src,dest);

  1. //删除文件夹
  2. File src = new File("D:\\aaa");
  3. FileUtils.deleteDirectory(src);

示例代码:(清空文件夹):文件夹里面的内容删除了,但是根文件夹还存在 

  1. //清空文件夹
  2. File src = new File("D:\\bbb");
  3. FileUtils.cleanDirectory(src);

8、Hutool工具包

官网: http:// https://hutool.cn/
API文档:https://apidoc.gitee.com/dromara/hutool/

中文使用文档:http:// https://hutool.cn/docs/#/
  

8.1、IO包的封装类

8.2、FileUtil类

  1. FileUtil类:
  2. file:根据参数创建一个file对象
  3. touch:根据参数创建文件
  4. writeLines:把集合中的数据写出到文件中,覆盖模式。
  5. appendLines:把集合中的数据写出到文件中,续写模式。
  6. readLines:指定字符编码,把文件中的数据,读到集合中。
  7. readUtf8Lines:按照UTF-8的形式,把文件中的数据,读到集合中
  8. copy:拷贝文件或者文件夹

  1. *//* File file1 = FileUtil.file("D:\\", "aaa", "bbb", "a.txt");
  2. System.out.println(file1);//D:\aaa\bbb\a.txt
  3. File touch = FileUtil.touch(file1);
  4. System.out.println(touch);
  5. ArrayList<String> list = new ArrayList<>();
  6. list.add("aaa");
  7. list.add("aaa");
  8. list.add("aaa");
  9. File file2 = FileUtil.writeLines(list, "D:\\a.txt", "UTF-8");
  10. System.out.println(file2);*//*
  11. *//* ArrayList<String> list = new ArrayList<>();
  12. list.add("aaa");
  13. list.add("aaa");
  14. list.add("aaa");
  15. File file3 = FileUtil.appendLines(list, "D:\\a.txt", "UTF-8");
  16. System.out.println(file3);*//*
  17. List<String> list = FileUtil.readLines("D:\\a.txt", "UTF-8");
  18. System.out.println(list);
  19. }

九、综合练习

1、制造假数据

  1. package com.yaqi.myiotest1;
  2. import java.io.BufferedWriter;
  3. import java.io.FileWriter;
  4. import java.io.IOException;
  5. import java.io.InputStreamReader;
  6. import java.net.URL;
  7. import java.net.URLConnection;
  8. import java.util.ArrayList;
  9. import java.util.Collections;
  10. import java.util.HashSet;
  11. import java.util.Random;
  12. import java.util.regex.Matcher;
  13. import java.util.regex.Pattern;
  14. public class Test1 {
  15. public static void main(String[] args) throws IOException {
  16. /*
  17. 制造假数据:
  18. 获取姓氏:https://hanyu.baidu.com/shici/detail?pid=0b2f26d4c0ddb3ee693fdb1137ee1b0d&from=kg0
  19. 获取男生名字:http://www.haoming8.cn/baobao/10881.html
  20. 获取女生名字:http://www.haoming8.cn/baobao/7641.html
  21. */
  22. //1.定义变量记录网址
  23. String familyNameNet = "https://hanyu.baidu.com/shici/detail?pid=0b2f26d4c0ddb3ee693fdb1137ee1b0d&from=kg0";
  24. String boyNameNet = "http://www.haoming8.cn/baobao/10881.html";
  25. String girlNameNet = "http://www.haoming8.cn/baobao/7641.html";
  26. //2.爬取数据,把网址上所有的数据拼接成一个字符串
  27. String familyNameStr = webCrawler(familyNameNet);
  28. String boyNameStr = webCrawler(boyNameNet);
  29. String girlNameStr = webCrawler(girlNameNet);
  30. //3.通过正则表达式,把其中符合要求的数据获取出来
  31. ArrayList<String> familyNameTempList = getData(familyNameStr,"(.{4})(,|。)",1);
  32. ArrayList<String> boyNameTempList = getData(boyNameStr,"([\\u4E00-\\u9FA5]{2})(、|。)",1);
  33. ArrayList<String> girlNameTempList = getData(girlNameStr,"(.. ){4}..",0);
  34. //4.处理数据
  35. //familyNameTempList(姓氏)
  36. //处理方案:把每一个姓氏拆开并添加到一个新的集合当中
  37. ArrayList<String> familyNameList = new ArrayList<>();
  38. for (String str : familyNameTempList) {
  39. //str 赵钱孙李 周吴郑王 冯陈褚卫 蒋沈韩杨
  40. for (int i = 0; i < str.length(); i++) {
  41. char c = str.charAt(i);
  42. familyNameList.add(c + "");
  43. }
  44. }
  45. //boyNameTempList(男生的名字)
  46. //处理方案:去除其中的重复元素
  47. ArrayList<String> boyNameList = new ArrayList<>();
  48. for (String str : boyNameTempList) {
  49. if(!boyNameList.contains(str)){
  50. boyNameList.add(str);
  51. }
  52. }
  53. //girlNameTempList(女生的名字)
  54. //处理方案:把里面的每一个元素用空格进行切割,得到每一个女生的名字
  55. ArrayList<String> girlNameList = new ArrayList<>();
  56. for (String str : girlNameTempList) {
  57. String[] arr = str.split(" ");
  58. for (int i = 0; i < arr.length; i++) {
  59. girlNameList.add(arr[i]);
  60. }
  61. }
  62. //5.生成数据
  63. //姓名(唯一)-性别-年龄
  64. ArrayList<String> list = getInfos(familyNameList, boyNameList, girlNameList, 70, 50);
  65. Collections.shuffle(list);
  66. //6.写出数据
  67. BufferedWriter bw = new BufferedWriter(new FileWriter("myiotest\\names.txt"));
  68. for (String str : list) {
  69. bw.write(str);
  70. bw.newLine();
  71. }
  72. bw.close();
  73. }
  74. /*
  75. * 作用:
  76. * 获取男生和女生的信息:张三-男-23
  77. *
  78. * 形参:
  79. * 参数一:装着姓氏的集合
  80. * 参数二:装着男生名字的集合
  81. * 参数三:装着女生名字的集合
  82. * 参数四:男生的个数
  83. * 参数五:女生的个数
  84. * */
  85. public static ArrayList<String> getInfos(ArrayList<String> familyNameList,ArrayList<String> boyNameList,ArrayList<String> girlNameList, int boyCount,int girlCount){
  86. //1.生成男生不重复的名字
  87. HashSet<String> boyhs = new HashSet<>();
  88. while (true){
  89. if(boyhs.size() == boyCount){
  90. break;
  91. }
  92. //随机
  93. Collections.shuffle(familyNameList);
  94. Collections.shuffle(boyNameList);
  95. boyhs.add(familyNameList.get(0) + boyNameList.get(0));
  96. }
  97. //2.生成女生不重复的名字
  98. HashSet<String> girlhs = new HashSet<>();
  99. while (true){
  100. if(girlhs.size() == girlCount){
  101. break;
  102. }
  103. //随机
  104. Collections.shuffle(familyNameList);
  105. Collections.shuffle(girlNameList);
  106. girlhs.add(familyNameList.get(0) + girlNameList.get(0));
  107. }
  108. //3.生成男生的信息并添加到集合当中
  109. ArrayList<String> list = new ArrayList<>();
  110. Random r = new Random();
  111. //【18 ~ 27】
  112. for (String boyName : boyhs) {
  113. //boyName依次表示每一个男生的名字
  114. int age = r.nextInt(10) + 18;
  115. list.add(boyName + "-男-" + age);
  116. }
  117. //4.生成女生的信息并添加到集合当中
  118. //【18 ~ 25】
  119. for (String girlName : girlhs) {
  120. //girlName依次表示每一个女生的名字
  121. int age = r.nextInt(8) + 18;
  122. list.add(girlName + "-女-" + age);
  123. }
  124. return list;
  125. }
  126. /*
  127. * 作用:根据正则表达式获取字符串中的数据
  128. * 参数一:
  129. * 完整的字符串
  130. * 参数二:
  131. * 正则表达式
  132. * 参数三:
  133. * 获取数据
  134. * 0:获取符合正则表达式所有的内容
  135. * 1:获取正则表达式中第一组数据
  136. * 2:获取正则表达式中第二组数据
  137. * ...以此类推
  138. *
  139. * 返回值:
  140. * 真正想要的数据
  141. *
  142. * */
  143. private static ArrayList<String> getData(String str, String regex,int index) {
  144. //1.创建集合存放数据
  145. ArrayList<String> list = new ArrayList<>();
  146. //2.按照正则表达式的规则,去获取数据
  147. Pattern pattern = Pattern.compile(regex);
  148. //按照pattern的规则,到str当中获取数据
  149. Matcher matcher = pattern.matcher(str);
  150. while (matcher.find()){
  151. list.add(matcher.group(index));
  152. }
  153. return list;
  154. }
  155. /*
  156. * 作用:
  157. * 从网络中爬取数据,把数据拼接成字符串返回
  158. * 形参:
  159. * 网址
  160. * 返回值:
  161. * 爬取到的所有数据
  162. * */
  163. public static String webCrawler(String net) throws IOException {
  164. //1.定义StringBuilder拼接爬取到的数据
  165. StringBuilder sb = new StringBuilder();
  166. //2.创建一个URL对象
  167. URL url = new URL(net);
  168. //3.链接上这个网址
  169. //细节:保证网络是畅通的,而且这个网址是可以链接上的。
  170. URLConnection conn = url.openConnection();
  171. //4.读取数据
  172. InputStreamReader isr = new InputStreamReader(conn.getInputStream());
  173. int ch;
  174. while ((ch = isr.read()) != -1){
  175. sb.append((char)ch);
  176. }
  177. //5.释放资源
  178. isr.close();
  179. //6.把读取到的数据返回
  180. return sb.toString();
  181. }
  182. }

1.1、爬取姓氏

  1. /*
  2. * 作用:
  3. * 从网络中爬取数据,把数据拼接成字符串返回
  4. * 形参:
  5. * 网址
  6. * 返回值:
  7. * 爬取到的所有数据
  8. * */
  9. public static String webCrawler(String net) throws IOException {
  10. //1.定义StringBuilder拼接爬取到的数据
  11. StringBuilder sb = new StringBuilder();
  12. //2.创建一个URL对象
  13. URL url = new URL(net);
  14. //3.链接上这个网址
  15. //细节:保证网络是畅通的,而且这个网址是可以链接上的。
  16. URLConnection conn = url.openConnection();
  17. //4.读取数据
  18. InputStreamReader isr = new InputStreamReader(conn.getInputStream());
  19. int ch;
  20. while ((ch = isr.read()) != -1){
  21. sb.append((char)ch);
  22. }
  23. //5.释放资源
  24. isr.close();
  25. //6.把读取到的数据返回
  26. return sb.toString();
  27. }
  28. }

  1. /*
  2. * 作用:根据正则表达式获取字符串中的数据
  3. * 参数一:
  4. * 完整的字符串
  5. * 参数二:
  6. * 正则表达式
  7. * 参数三:
  8. * 获取数据
  9. * 0:获取符合正则表达式所有的内容
  10. * 1:获取正则表达式中第一组数据
  11. * 2:获取正则表达式中第二组数据
  12. * ...以此类推
  13. *
  14. * 返回值:
  15. * 真正想要的数据
  16. *
  17. * */
  18. private static ArrayList<String> getData(String str, String regex,int index) {
  19. //1.创建集合存放数据
  20. ArrayList<String> list = new ArrayList<>();
  21. //2.按照正则表达式的规则,去获取数据
  22. Pattern pattern = Pattern.compile(regex);
  23. //按照pattern的规则,到str当中获取数据
  24. Matcher matcher = pattern.matcher(str);
  25. while (matcher.find()){
  26. list.add(matcher.group(index));
  27. }
  28. return list;
  29. }
  1. /*
  2. 制造假数据:
  3. 获取姓氏:https://hanyu.baidu.com/shici/detail?pid=0b2f26d4c0ddb3ee693fdb1137ee1b0d&from=kg0
  4. 获取男生名字:http://www.haoming8.cn/baobao/10881.html
  5. 获取女生名字:http://www.haoming8.cn/baobao/7641.html
  6. */
  7. //1.定义变量记录网址
  8. String familyNameNet = "https://hanyu.baidu.com/shici/detail?pid=0b2f26d4c0ddb3ee693fdb1137ee1b0d&from=kg0";
  9. String boyNameNet = "http://www.haoming8.cn/baobao/10881.html";
  10. String girlNameNet = "http://www.haoming8.cn/baobao/7641.html";
  11. //2.爬取数据,把网址上所有的数据拼接成一个字符串
  12. String familyNameStr = webCrawler(familyNameNet);
  13. String boyNameStr = webCrawler(boyNameNet);
  14. String girlNameStr = webCrawler(girlNameNet);
  15. //3.通过正则表达式,把其中符合要求的数据获取出来
  16. ArrayList<String> familyNameTempList = getData(familyNameStr,"(.{4})(,|。)",1);
  17. ArrayList<String> boyNameTempList = getData(boyNameStr,"([\\u4E00-\\u9FA5]{2})(、|。)",1);
  18. ArrayList<String> girlNameTempList = getData(girlNameStr,"(.. ){4}..",0);

1.2、爬取名字

  1. //3.通过正则表达式,把其中符合要求的数据获取出来
  2. ArrayList<String> familyNameTempList = getData(familyNameStr,"(.{4})(,|。)",1);
  3. ArrayList<String> boyNameTempList = getData(boyNameStr,"([\\u4E00-\\u9FA5]{2})(、|。)",1);
  4. ArrayList<String> girlNameTempList = getData(girlNameStr,"(.. ){4}..",0);

1.3、数据处理

  1. //4.处理数据
  2. //familyNameTempList(姓氏)
  3. //处理方案:把每一个姓氏拆开并添加到一个新的集合当中
  4. ArrayList<String> familyNameList = new ArrayList<>();
  5. for (String str : familyNameTempList) {
  6. //str 赵钱孙李 周吴郑王 冯陈褚卫 蒋沈韩杨
  7. for (int i = 0; i < str.length(); i++) {
  8. char c = str.charAt(i);
  9. familyNameList.add(c + "");
  10. }
  11. }
  12. //boyNameTempList(男生的名字)
  13. //处理方案:去除其中的重复元素
  14. ArrayList<String> boyNameList = new ArrayList<>();
  15. for (String str : boyNameTempList) {
  16. if(!boyNameList.contains(str)){
  17. boyNameList.add(str);
  18. }
  19. }
  20. //girlNameTempList(女生的名字)
  21. //处理方案:把里面的每一个元素用空格进行切割,得到每一个女生的名字
  22. ArrayList<String> girlNameList = new ArrayList<>();
  23. for (String str : girlNameTempList) {
  24. String[] arr = str.split(" ");
  25. for (int i = 0; i < arr.length; i++) {
  26. girlNameList.add(arr[i]);
  27. }
  28. }

1.4、数据处理并写出

  1. //5.生成数据
  2. //姓名(唯一)-性别-年龄
  3. ArrayList<String> list = getInfos(familyNameList, boyNameList, girlNameList, 70, 50);
  4. Collections.shuffle(list);
  5. //6.写出数据
  6. BufferedWriter bw = new BufferedWriter(new FileWriter("myiotest\\names.txt"));
  7. for (String str : list) {
  8. bw.write(str);
  9. bw.newLine();
  10. }
  11. bw.close();
  12. }
  13. /*
  14. * 作用:
  15. * 获取男生和女生的信息:张三-男-23
  16. *
  17. * 形参:
  18. * 参数一:装着姓氏的集合
  19. * 参数二:装着男生名字的集合
  20. * 参数三:装着女生名字的集合
  21. * 参数四:男生的个数
  22. * 参数五:女生的个数
  23. * */
  24. public static ArrayList<String> getInfos(ArrayList<String> familyNameList,ArrayList<String> boyNameList,ArrayList<String> girlNameList, int boyCount,int girlCount){
  25. //1.生成男生不重复的名字
  26. HashSet<String> boyhs = new HashSet<>();
  27. while (true){
  28. if(boyhs.size() == boyCount){
  29. break;
  30. }
  31. //随机
  32. Collections.shuffle(familyNameList);
  33. Collections.shuffle(boyNameList);
  34. boyhs.add(familyNameList.get(0) + boyNameList.get(0));
  35. }
  36. //2.生成女生不重复的名字
  37. HashSet<String> girlhs = new HashSet<>();
  38. while (true){
  39. if(girlhs.size() == girlCount){
  40. break;
  41. }
  42. //随机
  43. Collections.shuffle(familyNameList);
  44. Collections.shuffle(girlNameList);
  45. girlhs.add(familyNameList.get(0) + girlNameList.get(0));
  46. }
  47. //3.生成男生的信息并添加到集合当中
  48. ArrayList<String> list = new ArrayList<>();
  49. Random r = new Random();
  50. //【18 ~ 27】
  51. for (String boyName : boyhs) {
  52. //boyName依次表示每一个男生的名字
  53. int age = r.nextInt(10) + 18;
  54. list.add(boyName + "-男-" + age);
  55. }
  56. //4.生成女生的信息并添加到集合当中
  57. //【18 ~ 25】
  58. for (String girlName : girlhs) {
  59. //girlName依次表示每一个女生的名字
  60. int age = r.nextInt(8) + 18;
  61. list.add(girlName + "-女-" + age);
  62. }
  63. return list;
  64. }
  1. //6.写出数据
  2. BufferedWriter bw = new BufferedWriter(new FileWriter("myiotest\\names.txt"));
  3. for (String str : list) {
  4. bw.write(str);
  5. bw.newLine();
  6. }
  7. bw.close();

1.5、利用HuTool包生成假数据

  1. package com.yaqi.myiotest1;
  2. import cn.hutool.core.io.FileUtil;
  3. import cn.hutool.core.util.ReUtil;
  4. import cn.hutool.http.HttpUtil;
  5. import java.util.*;
  6. public class Test2 {
  7. public static void main(String[] args){
  8. //利用糊涂包生成假数据,并写到文件当中
  9. //1. 定义网址
  10. String familyNameNet = "https://hanyu.baidu.com/shici/detail?pid=0b2f26d4c0ddb3ee693fdb1137ee1b0d&from=kg0";
  11. String boyNameNet = "http://www.haoming8.cn/baobao/10881.html";
  12. String girlNameNet = "http://www.haoming8.cn/baobao/7641.html";
  13. //2.爬取数据
  14. String familyNameStr = HttpUtil.get(familyNameNet);
  15. String boyNameStr = HttpUtil.get(boyNameNet);
  16. String girlNameStr = HttpUtil.get(girlNameNet);
  17. //3.利用正则表达式获取数据
  18. //通过正则表达式,把其中符合要求的数据获取出来
  19. List<String> familyNameTempList = ReUtil.findAll("(.{4})(,|。)", familyNameStr, 1);
  20. List<String> boyNameTempList = ReUtil.findAll("([\\u4E00-\\u9FA5]{2})(、|。)", boyNameStr, 1);
  21. List<String> girlNameTempList = ReUtil.findAll("(.. ){4}..", girlNameStr, 0);
  22. System.out.println(familyNameTempList);
  23. System.out.println(boyNameTempList);
  24. System.out.println(girlNameTempList);
  25. //4.处理数据
  26. //familyNameTempList(姓氏)
  27. //处理方案:把每一个姓氏拆开并添加到一个新的集合当中
  28. ArrayList<String> familyNameList = new ArrayList<>();
  29. for (String str : familyNameTempList) {
  30. //str 赵钱孙李 周吴郑王 冯陈褚卫 蒋沈韩杨
  31. for (int i = 0; i < str.length(); i++) {
  32. char c = str.charAt(i);
  33. familyNameList.add(c + "");
  34. }
  35. }
  36. //boyNameTempList(男生的名字)
  37. //处理方案:去除其中的重复元素
  38. ArrayList<String> boyNameList = new ArrayList<>();
  39. for (String str : boyNameTempList) {
  40. if(!boyNameList.contains(str)){
  41. boyNameList.add(str);
  42. }
  43. }
  44. //girlNameTempList(女生的名字)
  45. //处理方案:把里面的每一个元素用空格进行切割,得到每一个女生的名字
  46. ArrayList<String> girlNameList = new ArrayList<>();
  47. for (String str : girlNameTempList) {
  48. String[] arr = str.split(" ");
  49. for (int i = 0; i < arr.length; i++) {
  50. girlNameList.add(arr[i]);
  51. }
  52. }
  53. //5.生成数据
  54. //姓名(唯一)-性别-年龄
  55. ArrayList<String> list = getInfos(familyNameList, boyNameList, girlNameList, 70, 50);
  56. Collections.shuffle(list);
  57. //6.写出数据
  58. //细节:
  59. //糊涂包的相对路径,不是相对于当前项目而言的,而是相对class文件而言的
  60. FileUtil.writeLines(list,"D:\\names.txt","UTF-8");
  61. }
  62. /*
  63. * 作用:
  64. * 获取男生和女生的信息:张三-男-23
  65. *
  66. * 形参:
  67. * 参数一:装着姓氏的集合
  68. * 参数二:装着男生名字的集合
  69. * 参数三:装着女生名字的集合
  70. * 参数四:男生的个数
  71. * 参数五:女生的个数
  72. * */
  73. public static ArrayList<String> getInfos(ArrayList<String> familyNameList,ArrayList<String> boyNameList,ArrayList<String> girlNameList, int boyCount,int girlCount){
  74. //1.生成男生不重复的名字
  75. HashSet<String> boyhs = new HashSet<>();
  76. while (true){
  77. if(boyhs.size() == boyCount){
  78. break;
  79. }
  80. //随机
  81. Collections.shuffle(familyNameList);
  82. Collections.shuffle(boyNameList);
  83. boyhs.add(familyNameList.get(0) + boyNameList.get(0));
  84. }
  85. //2.生成女生不重复的名字
  86. HashSet<String> girlhs = new HashSet<>();
  87. while (true){
  88. if(girlhs.size() == girlCount){
  89. break;
  90. }
  91. //随机
  92. Collections.shuffle(familyNameList);
  93. Collections.shuffle(girlNameList);
  94. girlhs.add(familyNameList.get(0) + girlNameList.get(0));
  95. }
  96. //3.生成男生的信息并添加到集合当中
  97. ArrayList<String> list = new ArrayList<>();
  98. Random r = new Random();
  99. //【18 ~ 27】
  100. for (String boyName : boyhs) {
  101. //boyName依次表示每一个男生的名字
  102. int age = r.nextInt(10) + 18;
  103. list.add(boyName + "-男-" + age);
  104. }
  105. //4.生成女生的信息并添加到集合当中
  106. //【18 ~ 25】
  107. for (String girlName : girlhs) {
  108. //girlName依次表示每一个女生的名字
  109. int age = r.nextInt(8) + 18;
  110. list.add(girlName + "-女-" + age);
  111. }
  112. return list;
  113. }
  114. }

2、随机点名器

2.1、练习1:普通随机点名

2.2、练习2:加入了概率和统计

2.3、练习3:作弊功能

2.4、练习4:随机不能重复,自动开启第二轮

2.5、练习5:带权重的随机

  1. package com.yaqi.myiotest6;
  2. import java.io.*;
  3. import java.util.ArrayList;
  4. import java.util.Arrays;
  5. public class Test {
  6. public static void main(String[] args) throws IOException {
  7. //1.把文件中所有的学生信息读取到内存中
  8. ArrayList<Student> list = new ArrayList<>();
  9. BufferedReader br = new BufferedReader(new FileReader("myiotest\\src\\com\\itheima\\myiotest6\\names.txt"));
  10. String line;
  11. while((line = br.readLine()) != null){
  12. String[] arr = line.split("-");
  13. Student stu = new Student(arr[0],arr[1],Integer.parseInt(arr[2]),Double.parseDouble(arr[3]));
  14. list.add(stu);
  15. }
  16. br.close();
  17. //2.计算权重的总和
  18. double weight = 0;
  19. for (Student stu : list) {
  20. weight = weight + stu.getWeight();
  21. }
  22. //3.计算每一个人的实际占比
  23. //[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
  24. double[] arr = new double[list.size()];
  25. int index = 0;
  26. for (Student stu : list) {
  27. arr[index] = stu.getWeight() / weight;
  28. index++;
  29. }
  30. //4.计算每一个人的权重占比范围
  31. for (int i = 1; i < arr.length; i++) {
  32. arr[i] = arr[i] + arr[i - 1];
  33. }
  34. //5.随机抽取
  35. //获取一个0.0~1.0之间的随机数
  36. double number = Math.random();
  37. //判断number在arr中的位置
  38. //二分查找法
  39. //方法回返回: - 插入点 - 1
  40. //获取number这个数据在数组当中的插入点位置
  41. int result = -Arrays.binarySearch(arr, number) - 1;
  42. Student stu = list.get(result);
  43. System.out.println(stu);
  44. //6.修改当前学生的权重
  45. double w = stu.getWeight() / 2;
  46. stu.setWeight(w);
  47. //7.把集合中的数据再次写到文件中
  48. BufferedWriter bw = new BufferedWriter(new FileWriter("myiotest\\src\\com\\itheima\\myiotest6\\names.txt"));
  49. for (Student s : list) {
  50. bw.write(s.toString());
  51. bw.newLine();
  52. }
  53. bw.close();
  54. }
  55. }

 javabean

  1. package com.yaqi.myiotest6;
  2. public class Student {
  3. private String name;
  4. private String gender;
  5. private int age;
  6. private double weight;
  7. public Student() {
  8. }
  9. public Student(String name, String gender, int age, double weight) {
  10. this.name = name;
  11. this.gender = gender;
  12. this.age = age;
  13. this.weight = weight;
  14. }
  15. /**
  16. * 获取
  17. *
  18. * @return name
  19. */
  20. public String getName() {
  21. return name;
  22. }
  23. /**
  24. * 设置
  25. *
  26. * @param name
  27. */
  28. public void setName(String name) {
  29. this.name = name;
  30. }
  31. /**
  32. * 获取
  33. *
  34. * @return gender
  35. */
  36. public String getGender() {
  37. return gender;
  38. }
  39. /**
  40. * 设置
  41. *
  42. * @param gender
  43. */
  44. public void setGender(String gender) {
  45. this.gender = gender;
  46. }
  47. /**
  48. * 获取
  49. *
  50. * @return age
  51. */
  52. public int getAge() {
  53. return age;
  54. }
  55. /**
  56. * 设置
  57. *
  58. * @param age
  59. */
  60. public void setAge(int age) {
  61. this.age = age;
  62. }
  63. /**
  64. * 获取
  65. *
  66. * @return weight
  67. */
  68. public double getWeight() {
  69. return weight;
  70. }
  71. /**
  72. * 设置
  73. *
  74. * @param weight
  75. */
  76. public void setWeight(double weight) {
  77. this.weight = weight;
  78. }
  79. public String toString() {
  80. return name + "-" + gender + "-" + age + "-" + weight;
  81. }
  82. }

3、登录注册

3.1、练习1:写一个登录小案例

  1. import java.io.BufferedReader;
  2. import java.io.FileReader;
  3. import java.io.IOException;
  4. import java.util.Scanner;
  5. public class Test {
  6. public static void main(String[] args) throws IOException {
  7. /*
  8. 需求:写一个登陆小案例。
  9. 步骤:
  10. 将正确的用户名和密码手动保存在本地的userinfo.txt文件中。
  11. 保存格式为:username=zhangsan&password=123
  12. 让用户键盘录入用户名和密码
  13. 比较用户录入的和正确的用户名密码是否一致
  14. 如果一致则打印登陆成功
  15. 如果不一致则打印登陆失败
  16. */
  17. //1.读取正确的用户名和密码
  18. BufferedReader br = new BufferedReader(new FileReader("myiotest\\src\\com\\yaqi\\myiotest7\\userinfo.txt"));
  19. String line = br.readLine();//username=zhangsan&password=123
  20. br.close();
  21. String[] userInfo = line.split("&");
  22. String[] arr1 = userInfo[0].split("=");
  23. String[] arr2 = userInfo[1].split("=");
  24. String rightUsername = arr1[1];
  25. String rightPassword = arr2[1];
  26. //2.用户键盘录入用户名和密码
  27. Scanner sc = new Scanner(System.in);
  28. System.out.println("请输入用户名");
  29. String username = sc.nextLine();
  30. System.out.println("请输入密码");
  31. String password = sc.nextLine();
  32. //3.比较
  33. if(rightUsername.equals(username) && rightPassword.equals(password)){
  34. System.out.println("登陆成功");
  35. }else{
  36. System.out.println("登陆失败");
  37. }
  38. }
  39. }

3.2、练习2:添加锁定账号功能

与练习1的区别

  1. package com.yaqi.myiotest8;
  2. import java.io.*;
  3. import java.util.Scanner;
  4. public class Test {
  5. public static void main(String[] args) throws IOException {
  6. /*
  7. 需求:写一个登陆小案例(添加锁定账号功能)
  8. 步骤:
  9. 将正确的用户名和密码手动保存在本地的userinfo.txt文件中。
  10. 保存格式为:username=zhangsan&password=123&count=0
  11. 让用户键盘录入用户名和密码
  12. 比较用户录入的和正确的用户名密码是否一致
  13. 如果一致则打印登陆成功
  14. 如果不一致则打印登陆失败,连续输错三次被锁定
  15. */
  16. //1.读取正确的用户名和密码
  17. BufferedReader br = new BufferedReader(new FileReader("myiotest\\src\\com\\yaqi\\myiotest8\\userinfo.txt"));
  18. String line = br.readLine();//username=zhangsan&password=123&count=0
  19. br.close();
  20. String[] userInfo = line.split("&");
  21. String[] arr1 = userInfo[0].split("=");
  22. String[] arr2 = userInfo[1].split("=");
  23. String[] arr3 = userInfo[2].split("=");
  24. String rightUsername = arr1[1];
  25. String rightPassword = arr2[1];
  26. //count:表示用户连续输错的次数
  27. int count = Integer.parseInt(arr3[1]);
  28. //2.用户键盘录入用户名和密码
  29. Scanner sc = new Scanner(System.in);
  30. System.out.println("请输入用户名");
  31. String username = sc.nextLine();
  32. System.out.println("请输入密码");
  33. String password = sc.nextLine();
  34. //3.比较
  35. if (rightUsername.equals(username) && rightPassword.equals(password) && count < 3) {
  36. System.out.println("登陆成功");
  37. writeInfo("username=" + rightUsername + "&password=" + rightPassword + "&count=0");
  38. } else {
  39. count++;
  40. if (count < 3) {
  41. System.out.println("登陆失败,还剩下" + (3 - count) + "次机会");
  42. } else {
  43. System.out.println("用户账户被锁定");
  44. }
  45. writeInfo("username=" + rightUsername + "&password=" + rightPassword + "&count=" + count);
  46. }
  47. }
  48. /*
  49. * 作用:
  50. * 写出一个字符串到本地文件中
  51. * 参数:
  52. * 要写出的字符串
  53. * */
  54. public static void writeInfo(String content) throws IOException {
  55. BufferedWriter bw = new BufferedWriter(new FileWriter("myiotest\\src\\com\\yaqi\\myiotest8\\userinfo.txt"));
  56. bw.write(content);
  57. bw.close();
  58. }
  59. }

3.3、练习3:补全拼图小游戏的登录注册(考虑多个用户)

导入项目:先将模块文件夹复制到你想要导入到的项目文件夹中,然后通过文件结构中的添加模块将该模块导入

打开界面时就通过IO来读取用户信息,且该代码需要写在构造方法中

Ⅰ、登录

示例代码1:读取本地文件中的用户信息 —— 登录 

  1. //读取本地文件中的用户信息
  2. private void readUserInfo() {
  3. //1.读取数据
  4. List<String> userInfoStrList = FileUtil.readUtf8Lines("E:\\ideaProjects\\basic-code\\puzzlegame\\userinfo.txt");
  5. //2.遍历集合获取用户信息并创建User对象
  6. for (String str : userInfoStrList) {
  7. //username=zhangsan&password=123
  8. String[] userInfoArr = str.split("&");
  9. //0 username=zhangsan 1 password=123
  10. String[] arr1 = userInfoArr[0].split("=");
  11. String[] arr2 = userInfoArr[1].split("=");
  12. User u = new User(arr1[1],arr2[1]);
  13. allUsers.add(u);
  14. }
  15. System.out.println(allUsers);
  16. }

 

Ⅱ、注册 

示例代码2:读取本地文件中的用户信息 —— 注册

重置:清空三个输入框

  1. else if(e.getSource() == reset){
  2. //点击了重置按钮
  3. //清空三个输入框
  4. username.setText("");
  5. password.setText("");
  6. rePassword.setText("");

 注册:

  1. /*
  2. * 作用:
  3. * 判断username在集合中是否存在
  4. * 参数:
  5. * 用户名
  6. * 返回值:
  7. * true:存在
  8. * false:不存在
  9. *
  10. * */
  11. public boolean containsUsername(String username){
  12. for (User u : allUsers) {
  13. if(u.getUsername().equals(username)){
  14. return true;
  15. }
  16. }
  17. return false;
  18. }
  1. if(e.getSource() == submit){
  2. //点击了注册按钮
  3. //1.用户名,密码不能为空
  4. if(username.getText().length() == 0 || password.getText().length() == 0 || rePassword.getText().length() == 0){
  5. showDialog("用户名和密码不能为空");
  6. return;
  7. }
  8. //2.判断两次密码输入是否一致
  9. if(!password.getText().equals(rePassword.getText())){
  10. showDialog("两次密码输入不一致");
  11. return;
  12. }
  13. //3.判断用户名和密码的格式是否正确
  14. if(!username.getText().matches("[a-zA-Z0-9]{4,16}")){
  15. showDialog("用户名不符合规则");
  16. return;
  17. }
  18. if(!password.getText().matches("\\S*(?=\\S{6,})(?=\\S*\\d)(?=\\S*[a-z])\\S*")){
  19. showDialog("密码不符合规则,至少包含1个小写字母,1个数字,长度至少6位");
  20. return;
  21. }
  22. //4.判断用户名是否已经重复
  23. if(containsUsername(username.getText())){
  24. showDialog("用户名已经存在,请重新输入");
  25. return;
  26. }
  27. //5.添加用户
  28. allUsers.add(new User(username.getText(),password.getText()));
  29. //6.写入文件
  30. FileUtil.writeLines(allUsers,"E:\\ideaProjects\\basic-code\\puzzlegame\\userinfo.txt","UTF-8");
  31. //7.提示注册成功
  32. showDialog("注册成功");
  33. //关闭注册界面,打开登录界面
  34. this.setVisible(false);
  35. new LoginJFrame();

 

4、游戏的存档和读档

4.1、存档

Ⅰ、在菜单中添加“存档”和“读档”

Ⅱ、点击“存档后”,将游戏数据写到本地

创建GameInfo.java

 

 

 

4.2、读档

 

4.3、修改bug

bug1:刚打开游戏界面时,存档和读档都是空的

解决方法:在initJMenuBar()方法中添加getGameInfo方法

 

 

5、游戏配置

5.1、配置文件的优点

5.2、常见的配置文件

5.3、properties配置文件

5.4、Properties作为Map集合的操作

  1. package com.yaqi.myiotest9;
  2. import java.util.Properties;
  3. public class Test1 {
  4. public static void main(String[] args) {
  5. /*
  6. Properties作为Map集合的操作
  7. */
  8. //1.创建集合的对象
  9. Properties prop = new Properties();
  10. //2.添加数据
  11. //细节:虽然我们可以往Properties当中添加任意的数据类型,但是一般只会往里面添加字符串类型的数据
  12. prop.put("aaa","111");
  13. prop.put("bbb","222");
  14. prop.put("ccc","333");
  15. prop.put("ddd","444");
  16. //3.遍历集合
  17. /*Set<Object> keys = prop.keySet();
  18. for (Object key : keys) {
  19. Object value = prop.get(key);
  20. System.out.println(key + "=" + value);
  21. }*/
  22. /* Set<Map.Entry<Object, Object>> entries = prop.entrySet();
  23. for (Map.Entry<Object, Object> entry : entries) {
  24. Object key = entry.getKey();
  25. Object value = entry.getValue();
  26. System.out.println(key + "=" + value);
  27. }*/
  28. }
  29. }

5.5、Properties跟IO流结合的操作(store)

  1. import java.io.FileOutputStream;
  2. import java.io.IOException;
  3. import java.util.Properties;
  4. public class Test2 {
  5. public static void main(String[] args) throws IOException {
  6. /*
  7. Properties跟IO流结合的操作
  8. */
  9. //1.创建集合
  10. Properties prop = new Properties();
  11. //2.添加数据
  12. prop.put("aaa","bbb");
  13. prop.put("bbb","ccc");
  14. prop.put("ddd","eee");
  15. prop.put("fff","iii");
  16. //3.把集合中的数据以键值对的形式写到本地文件当中
  17. FileOutputStream fos = new FileOutputStream("myiotest\\a.properties");
  18. prop.store(fos,"test");
  19. fos.close();
  20. /*BufferedWriter bw = new BufferedWriter(new FileWriter("myiotest\\a.properties"));
  21. Set<Map.Entry<Object, Object>> entries = prop.entrySet();
  22. for (Map.Entry<Object, Object> entry : entries) {
  23. Object key = entry.getKey();
  24. Object value = entry.getValue();
  25. bw.write(key + "=" + value);
  26. bw.newLine();
  27. }
  28. bw.close();*/
  29. }
  30. }

5.6、读取Properties(load)

  1. package com.yaqi.myiotest9;
  2. import java.io.FileInputStream;
  3. import java.io.IOException;
  4. import java.util.Properties;
  5. public class Test3 {
  6. public static void main(String[] args) throws IOException {
  7. //1.创建集合
  8. Properties prop = new Properties();
  9. //2.读取本地Properties文件里面的数据
  10. FileInputStream fis = new FileInputStream("myiotest\\a.properties");
  11. prop.load(fis);
  12. fis.close();
  13. //3.打印集合
  14. System.out.println(prop);
  15. }
  16. }

 

5.7、拼图游戏的配置文件

4、每日一记(IO的最终大作业)

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/226600
推荐阅读
相关标签
  

闽ICP备14008679号