IO流的作用

以前是如何存储数据的?

  1. int a = 10;
  2. int [] arr = {1,2,3,4,5};
  3. ArrayList<String> list = new ArrayList<>();

通过变量,数组,或者集合存储数据,都是不能永久化存储 , 因为数据都是存储在内存中
只要代码运行结束,所有数据都会丢失。

学习IO流的目的?

1,将数据写到文件中,实现数据永久化存储
2,把文件中的数据读取到内存中(Java程序)

IO流概述

I 表示intput ,是数据从硬盘进内存的过程,称之为读数据。
O 表示output ,是数据从内存到硬盘的过程。称之为写数据。

在数据传输的过程中,是谁在读?是谁在写?这个参照物是谁?

IO的数据传输,可以看做是一种数据的流动,按照流动的方向,以内存为参照物,进行读写操作。
简单来说:内存在读,内存在写。

image.pngimage.png

字节流写数据入门

步骤:

①创建字节输出流对象。
注意事项:
如果文件不存在,就创建。
如果文件存在就清空。
②写数据
注意事项:
写出的整数,实际写出的是整数在码表上对应的字符。
③关:释放资源
注意事项:
每次使用完流必须要释放资源
第一部分 : 字节输出流类
OutputStream类 : 字节输出流最顶层的类 , 抽象类
public class FileOutputStream extends OutputStream
第二部分 : 构造方法
FileOutputStream类 :
public FileOutputStream(File file) : 往file类型的路径中写入数据
public FileOutputStream(String name) : 往String类型的路径中写入数据

_ public void write(int n) 写出单个字节 (只会写出第一个字节的数据)
public void close() 关闭流释放资源
第三部分 : 字节输出流步骤
1 创建字节输出流对象
2 写数据
3 释放资源

  1. public class OutputStreamDemo1 {
  2. public static void main(String[] args) throws IOException {
  3. //1 创 public FileOutputStream(String name) : 往String类型的路径中写入数据
  4. FileOutputStream fos = new FileOutputStream("day10_demo/file02.txt");
  5. //如果file02.txt 不存在帮你创建,存在则会清空原来的数据
  6. //2 写
  7. fos.write(97);//a
  8. fos.write(98);//b
  9. fos.write(99);//c
  10. fos.write('A');
  11. fos.write('B');
  12. fos.write('C');
  13. //3 关
  14. fos.close();//释放资源
  15. }
  16. }

运行效果如下:
image.png

字节流写数据的3种方式

1 void write(int b) 一次写一个字节数据
2 void write(byte[] b) 一次写一个字节数组数据
3 void write(byte[] b, int off, int len) 一次写一个字节数组的部分数据

  1. public class OutputStreamDemo2 {
  2. public static void main(String[] args) throws IOException {
  3. //1 创
  4. FileOutputStream fos = new FileOutputStream("day10_demo/file02.txt");
  5. //2 写
  6. //1 void write(int b) 一次写一个字节数据
  7. fos.write('A');
  8. //2 void write(byte[] b) 一次写一个字节数组数据
  9. byte[] brr = {97,98,99,100,101};//abcde
  10. fos.write(brr);
  11. //3 void write(byte[] b, int off, int len) 一次写一个字节数组的部分数据
  12. //d e
  13. fos.write(brr,3,2);//把数组brr从索引为3 的位置开始 写2个字节数据
  14. //3 关
  15. fos.close();
  16. //Aabcdede
  17. }
  18. }

运行效果如下:
image.png

字节流写数据换行与追加

字节流写数据的换行和追加写入

1 字节流写数据如何实现换行呢?
>写完数据后,加换行符
windows : \r\n
linux : \n mac : \r_2 字节流写数据如何实现追加写入呢?
> 通过构造方法 : public FileOutputStream(String name,boolean append)
>创建文件输出流以指定的名称写入文件。如果第二个参数为true ,不会清空文件里面的内容, 追加写数据

  1. public class OutputStreamDemo3 {
  2. public static void main(String[] args) throws IOException {
  3. //1 创
  4. //续写的话在路径后面加个true 不然默认是false会覆盖原有的数据
  5. //FileOutputStream fos = new FileOutputStream("day10_demo/file02.txt",true);
  6. FileOutputStream fos = new FileOutputStream("day10_demo/file02.txt");
  7. //2 写
  8. //1 void write(int b) 一次写一个字节数据
  9. fos.write('A');
  10. fos.write('\r');
  11. //2 void write(byte[] b) 一次写一个字节数组数据
  12. byte[] brr = {97,98,99,100,101};//abcde
  13. fos.write(brr);
  14. fos.write('\n');
  15. //3 void write(byte[] b, int off, int len) 一次写一个字节数组的部分数据
  16. //d e
  17. fos.write(brr,3,2);//把数组brr从索引为3 的位置开始 写2个字节数据
  18. //换行
  19. String huanhang = "\r\n"; //换行字符
  20. byte[] bytes = huanhang.getBytes(); //将字符串变成字节数组
  21. fos.write(bytes);//换行
  22. fos.write(brr,3,2);//把数组brr从索引为3 的位置开始 写2个字节数据
  23. fos.write(bytes);//换行
  24. //3 关
  25. fos.close();
  26. //A
  27. //abcde
  28. //de
  29. //de
  30. }
  31. }

运行效果如下:
image.png

字节输入流

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

步骤:
第一部分 : 字节输入流类 【创】
InputStream类 : 字节输入流最顶层的类 , 抽象类
—- FileInputStream类 : FileInputStream extends InputStream

注意事项: 如果文件不存在,就直接报错
第二部分 : 构造方法 【读】
public FileInputStream(File file) : 从file类型的路径中读取数据
public FileInputStream(String name) : 从字符串路径中读取数据
注意事项: 读出来的是文件中数据的码表值。 a —>97__ 读数据的方法 :
public int read() : 从此输入流中读取一个数据字节 , 读不到数据会返回-1

释放资源
publid void close() : 释放资源

_第三部分 : 字节输入流步骤 【关】
1 创建输入流对象
2 读数据
3 释放资源

注意事项: 每次使用完流必须要释放资源。

  1. public class FileInputStreamDemo1 {
  2. public static void main(String[] args) throws IOException {
  3. // 1.创
  4. FileInputStream fis = new FileInputStream("day10_demo/file02.txt");
  5. // 2.读
  6. // public int read() : 从此输入流中读取一个数据字节 , 读不到数据会返回-1
  7. int b;//临时保存读取的字节
  8. while ((b = fis.read()) != -1){
  9. //b在这里使用
  10. System.out.println((char) b);//强转字符
  11. }
  12. // System.out.println(fis.read());//97
  13. // System.out.println(fis.read());//98
  14. // System.out.println(fis.read());//99
  15. // System.out.println(fis.read());//100
  16. // System.out.println(fis.read());//-1 //读取到-1 就证明读取结束了
  17. // System.out.println(fis.read());//-1
  18. // 3.关
  19. fis.close();
  20. }
  21. }

案例:复制文件

需求:把“xxx.jpg”复制到当前模块下
复制图片
数据源 : D:\桌面\工具\Saved Pictures\鸿蒙.jpg
目的地 : day10_demo\鸿蒙.jpg

  1. public class FileInputStreamDemo7 {
  2. public static void main(String[] args) throws IOException {
  3. System.out.println("开始拷贝");
  4. String src = "D:\\桌面\\工具\\Saved Pictures\\鸿蒙.jpg"; //数据源
  5. String dest = "day10_demo\\hello\\鸿蒙.jpg";//目的地
  6. //1 创 输入 输出流
  7. FileInputStream fis = new FileInputStream(src); //输入流,读
  8. FileOutputStream fos = new FileOutputStream(dest);//输出流,写
  9. //2 读 写
  10. int b;
  11. while ((b = fis.read()) != -1){//将字节从资源文件中读取到内存中的b 变量保存
  12. //把b变量的数据写到目的地
  13. fos.write(b);
  14. }
  15. //3 关 [先开后关]
  16. fos.close();
  17. fis.close();
  18. System.out.println("结束拷贝");
  19. }
  20. }

IO资源的处理

image.png

  1. /*
  2. JDK7版本之前处理方式 :
  3. try...catch ...finally
  4. */
  5. public class FileInputStreamDemo4 {
  6. public static void main(String[] args) {
  7. System.out.println("开始拷贝");
  8. String src = "D:\\桌面\\工具\\Saved Pictures\\鸿蒙.jpg"; //数据源
  9. String dest = "day10_demo\\hello\\鸿蒙1.jpg";//目的地
  10. //1 创 输入 输出流
  11. FileInputStream fis = null;
  12. FileOutputStream fos = null;
  13. try {
  14. fis = new FileInputStream(src); //输入流,读
  15. fos = new FileOutputStream(dest);//输出流,写
  16. //2 读 写
  17. int b;
  18. while ((b = fis.read()) != -1) {//将字节从资源文件中读取到内存中的b 变量保存
  19. //把b变量的数据写到目的地
  20. fos.write(b);
  21. }
  22. } catch (IOException e) {
  23. e.printStackTrace();
  24. } finally {
  25. //3 关 [先开后关]
  26. try {
  27. if ( fos != null) {
  28. fos.close();
  29. }
  30. } catch (IOException e) {
  31. e.printStackTrace();
  32. }
  33. try {
  34. if (fis != null) {
  35. fis.close();
  36. }
  37. } catch (IOException e) {
  38. e.printStackTrace();
  39. }
  40. }
  41. System.out.println("结束拷贝");
  42. }
  43. }

image.png

  1. /*
  2. JDK7版本优化处理方式
  3. 需求 : 对上一个复制图片的代码进行使用捕获方式处理
  4. */
  5. public class FileInputStreamDemo3 {
  6. public static void main(String[] args) {
  7. System.out.println("开始拷贝");
  8. String src = "D:\\桌面\\工具\\Saved Pictures\\鸿蒙.jpg"; //数据源
  9. String dest = "day10_demo\\hello\\鸿蒙2.jpg";//目的地
  10. //1 创 输入 输出流
  11. try(
  12. FileInputStream fis = new FileInputStream(src); //输入流,读
  13. FileOutputStream fos = new FileOutputStream(dest);//输出流,写
  14. ) {
  15. //2 读 写
  16. int b;
  17. while ((b = fis.read()) != -1) {//将字节从资源文件中读取到内存中的b 变量保存
  18. //把b变量的数据写到目的地
  19. fos.write(b);
  20. }
  21. //3 关 [先开后关] 自动调用close方法
  22. //fos.close();
  23. //fis.close();
  24. }catch (IOException e){
  25. e.printStackTrace();
  26. }
  27. System.out.println("结束拷贝");
  28. }
  29. }

字节输入流-读字节数组

提高拷贝速度的解决方案:

需求1 : 在当前模块下创建一个文件 , 文件存储数据hello world , 定义长度为5的字节数组进行读取数据

  1. /*
  2. FileInputStream类 :
  3. public int read(byte[] b):
  4. 1 从输入流读取最多b.length个字节的数据
  5. 2 返回的是真实读到的数据个数
  6. 3 如果不到数据 , 那么会返回-1
  7. String类
  8. public String(byte[] bys) : 把字节数组中的内容转成一个字符串
  9. public String(byte[] bytes, int startIndex, int length) : 把字节数组的一部分转成字符串
  10. */
  11. public class FileInputStreamDemo5 {
  12. public static void main(String[] args) {
  13. try {
  14. FileInputStream fis = new FileInputStream("day10_demo/file01.txt");
  15. //读取
  16. /*int b;
  17. while ((b = fis.read()) != -1){
  18. System.out.print((char) b);
  19. }*/
  20. /*byte[] bytes = new byte[10];
  21. int len = fis.read(bytes);//读取的数据放到bytes 返回读取的字节个数
  22. System.out.println("len = " + len + "," + Arrays.toString(bytes));
  23. System.out.println("len = " + len + "," + new String(bytes));
  24. System.out.println("len = " + len + "," + new String(bytes,0,len));*/
  25. //借助循环读取
  26. byte[] buf = new byte[10];// 定义一个数组缓冲区,临时保存每次读取的字节
  27. int len;//临时保存每次读取的字节个数
  28. while ((len = fis.read(buf)) != -1){//len表示每次读取的有效字节个数
  29. //将读取的数据,转换成字符串
  30. String str = new String(buf,0,len);
  31. System.out.print(str);//打印读取的数据
  32. }
  33. } catch (IOException e) {
  34. e.printStackTrace();
  35. }
  36. }
  37. }

注意:汉字UTF-8占3字节,读取的时候3字节没被截断就可以输出汉字,不然那个汉字就乱码了

需求2 : 对复制图片的代码进行使用一次读写一个字节数组的方式进行改进

  1. public class FileInputStreamDemo7 {
  2. public static void main(String[] args) throws IOException {
  3. System.out.println("开始拷贝");
  4. String src = "D:\\桌面\\工具\\Saved Pictures\\鸿蒙.jpg"; //数据源
  5. String dest = "day10_demo\\hello\\鸿蒙.jpg";//目的地
  6. //1 创 输入 输出流
  7. FileInputStream fis = new FileInputStream(src); //输入流,读
  8. FileOutputStream fos = new FileOutputStream(dest);//输出流,写
  9. //2 读 写
  10. //public int read (byte[] buf) 一次读取多个字节,并返回有限读取的字节个数,读取完返回-1
  11. byte[] buf = new byte[1024 * 8];
  12. int len;
  13. while ((len = fis.read()) != -1){//一次读取多个字节放到buf,len保存的时候每次读取有效的字节个数
  14. //把读取的有效字节数据写到新文件中
  15. fos.write(buf,0,len);//有效的字节数据写出 删掉任何一个字符都打不开文件
  16. }
  17. //3 关 [先开后关]
  18. fos.close();
  19. fis.close();
  20. System.out.println("结束拷贝");
  21. }
  22. }

字节流缓冲流

_字节缓冲流:
BufferOutputStream:缓冲输出流
BufferedInputStream:缓冲输入流

构造方法:
字节缓冲输出流:BufferedOutputStream(OutputStream out)
字节缓冲输入流:BufferedInputStream(InputStream in)_

  1. public class BufferedStreamDemo2 {
  2. public static void main(String[] args) {
  3. //4 缓冲流一次读写一个字节数组
  4. long t1 = System.currentTimeMillis();
  5. //拷贝动作
  6. try(
  7. FileInputStream fis = new FileInputStream(src); //输入流,读
  8. BufferedInputStream bis = new BufferedInputStream(fis);
  9. FileOutputStream fos = new FileOutputStream(dest);//输出流,写
  10. BufferedOutputStream bos = new BufferedOutputStream(fos);
  11. ) {
  12. //2 读 写
  13. byte[] buf = new byte[8 * 1024];
  14. int b;
  15. while ((b = fis.read(buf)) != -1) {//将字节从资源文件中读取到内存中的b 变量保存
  16. //把b变量的数据写到目的地
  17. fos.write(buf,0,b);
  18. }
  19. //3 关 [先开后关] 自动调用close方法
  20. //fos.close();
  21. //fis.close();
  22. }catch (IOException e){
  23. e.printStackTrace();
  24. }
  25. long t2 = System.currentTimeMillis();
  26. System.out.println("高效流数组拷贝时间" + (t2 - t1));
  27. }
  28. }

File类 , IO流 , 递归
File类
java.io.File 类是文件和目录路径名的抽象表示形式,主要用于文件和目录的创建、查找和删除等操作。

文件和目录都使用File类来表示
文件和目录都使用路径来表示例如:code目录用路径表示 D:\abc\code美女.jpg文件用路径表示 D:\abc\美女.jpg
注意:路径是唯一的,同一台计算机中不可能存在有两个不同的文件但路径又相同。**

File类概述和构造方法
File:它是文件和目录路径名的抽象表示
文件和目录可以通过File封装成对象
File封装的对象仅仅是一个路径名。它可以是存在的,也可以是不存在的。

方法名 说明
File(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的File实例
File f1=new File();
File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的File实例
File(File parent, String child) 从父抽象路径名和子路径名字符串创建新的File实例

绝对路径和相对路径

绝对路径:从盘符开始
File file1 = new File(“D:\itheima\a.txt”);
相对路径:相对当前项目下的路径
只能表示项目里面的文件!
File file2 = new File(“a.txt”);
File file3 = new File(“模块名\a.txt”);

File类的创建功能
方法名 说明
public boolean createNewFile() 创建一个新的空的文件
public boolean mkdir() 创建一个单级文件夹
public boolean mkdirs() 创建一个多级文件夹

Mkdirs 可以之间创建单级或者多级文件夹
File f5 = new File(“day10_demo\a1\sss”);
boolean mkdirs = f5.mkdirs();

public boolean delete() 删除由此抽象路径名表示的文件或目录
删除目录时的注意事项:
delete方法直接删除不走回收站。
如果删除的是一个文件,直接删除。
如果删除的是一个文件夹,需要先删除文件夹中的内容,最后才能删除文件夹。
不能直接删除一个有文件的文件夹!

File类判断和获取功能

方法名 说明
public boolean isDirectory() 测试此抽象路径名表示的File是否为目录
public boolean isFile() 测试此抽象路径名表示的File是否为文件
public boolean exists() 测试此抽象路径名表示的File是否存在
public String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串
public String getPath() 将此抽象路径名转换为路径名字符串(构造路径)
public String getName() 返回由此抽象路径名表示的文件或目录的名称
(包含后缀.)
File类高级获取功能

public File[] listFiles() 返回此抽象路径名表示的目录中的文件和目录的File对象数组

listFiles方法注意事项:
当调用者不存在时,返回null
当调用者是一个文件时,返回null
当调用者是一个空文件夹时,返回一个长度为0的数组
当调用者是一个有内容的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回
当调用者是一个有隐藏文件的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏内容

IO流的概述和分类

以前是如何存储数据的?
int a = 10;
int [] arr = {1,2,3,4,5};
ArrayList list = new ArrayList<>();

通过变量,数组,或者集合存储数据,都是不能永久化存储 , 因为数据都是存储在内存中
只要代码运行结束,所有数据都会丢失。

学习IO流的目的?
1,将数据写到文件中,实现数据永久化存储
2,把文件中的数据读取到内存中(Java程序)

IO流概述

其中:
I 表示intput ,是数据从硬盘进内存的过程,称之为读数据。
O 表示output ,是数据从内存到硬盘的过程。称之为写数据。

在数据传输的过程中,是谁在读?是谁在写?这个参照物是谁?
IO的数据传输,可以看做是一种数据的流动,按照流动的方向,以内存为参照物,进行读写操作。
简单来说:内存在读,内存在写。

字节输出流

字节流写数据
步骤:
1.创建字节输出流对象。
注意事项:
如果文件不存在,就创建。
如果文件存在就清空。
2.写数据
注意事项:
写出的整数,实际写出的是整数在码表上对应的字符。
3.释放资源
注意事项:
每次使用完流必须要释放资源。
字节流写数据步骤?
第一步: 创建字节输出流对象
第二步: 写数据
第三步: 释放资源

创建字节输出流对象, 会不会自动创建文件 ?
如果文件不存在,会自动创建一个文件
如果文件存在, 会把文件中的内容清空

字节流写数据的3种方式

void write(int b) 一次写一个字节数据
void write(byte[] b) 一次写一个字节数组数据
void write(byte[] b, int off, int len) 一次写一个字节数组的部分数据
字节流写数据的换行和追加写入

字节流写数据如何实现换行呢?

写完数据后,加换行符
windows : \r\n
linux : \n
mac : \r

字节流写数据如何实现追加写入呢?

public FileOutputStream(String name,boolean append)
创建文件输出流以指定的名称写入文件。如果第二个参数为true ,不会清空文件里面的内容

字节流输出流小结:
步骤:
1.创建字节输出流对象
文件不存在,就创建。
文件存在就清空。如果不想被清空则加true
2.写数据
可以写一个字节,写一个字节数组,写一个字节数组的一部分
写一个回车换行:\r\n
3.释放资源
调用close方法,断开流与文件之间的关联

字节输入流

提高拷贝速度的解决方案

字节流读数据(一次读一个字节)
1创建字节输入流对象。
注意事项:
如果文件不存在,就直接报错。
2.读数据
注意事项:
读出来的是文件中数据的码表值。a->97
3.释放资源
注意事项:
每次使用完流必须要释放资源。

IO资源的处理

JDK7版本前异常的捕获处理
之前的入门练习,我们一直把异常抛出,而实际开发中异常建议捕获处理
如果使用捕获处理, 分析以下代码是否合理:

缓冲区流
Properties集合
ResourceBundle工具类
递归

思考:那么我们如何操作才能让close方法一定执行呢?
finally :在异常处理时提供finally块来执行所有释放资源操作
特点 :被finally控制的语句一定会执行,除非JVM退出

JDK7版本异常的捕获处理
格式:
try (创建流对象语句1 ; 创建流对象语句2 …) {
// 读写数据
} catch (IOException e) {
处理异常的代码…
}

举例:
try ( FileInputStream fis1 = new FileInputStream(“day11_demo\a.txt”) ;
FileInputStream fis2 = new FileInputStream(“day11_demo\b.txt”) )
{
// 读写数据
} catch (IOException e) {
处理异常的代码…
}

注意:
使用前提, 资源的类型必须是AutoCloseable接口的实现类

小结:

JDK7版本前捕获处理异常

使用try…catch…finally , 把释放资源操作,放在
finally代码块中,虽然一定可以释放资源
但是属于手动释放资源, 但是代码过于复杂

JDK7版本捕获处理异常优化

使用try-with-resource , 需要把流对象放在try的小扩中 , 流资源在使用完毕 , 会自动释放资源 , 代码相对于做了简化

字节缓冲流:

BufferOutputStream:缓冲输出流
BufferedInputStream:缓冲输入流

构造方法:
字节缓冲输出流:BufferedOutputStream(OutputStream out)
字节缓冲输入流:BufferedInputStream(InputStream in)

为什么构造方法需要的是字节流,而不是具体的文件或者路径呢?
字节缓冲流仅仅提供缓冲区,而真正的读写数据还得依靠基本的字节流对象进行操作

Properties
Properties概述:
是一个Map体系的集合类
Properties中有跟IO相关的方法
不需要加泛型.默认存储的是Object类型, 但是工作中只存字符串

Properties作为集合的特有方法:

方法名 说明
Object setProperty(String key, String value) 设置集合的键和值,都是String类型,相当于put方法
String getProperty(String key) 使用此属性列表中指定的键搜索属性,相当于get方法
Set stringPropertyNames() 从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串, 相当于keyset方法

Properties和IO流结合的方法:

方法名 说明
void load(InputStream inStream) 以字节流形式, 把文件中的键值对, 读取到集合中
void load(Reader reader) 以字符流形式, 把文件中的键值对, 读取到集合中
void store(OutputStream out, String comments) 把集合中的键值对,以字节流形式写入文件中 , 参数二为注释
void store(Writer writer, String comments) 把集合中的键值对,以字符流形式写入文件中 , 参数二为注释

递归概述

在之前我们在方法中是可以调用其他方法的,那么你试过方法自己调用自己吗 ?
代码体验一下!
1 其实递归就是方法本身自己调用自己

2 根据刚才的演示我们也看到了程序抛出一个异常 StackOverflowError(栈内存溢出)
所以以后使用递归必须要有停止条件(出口)

3 递归能给我们带来什么好处呢 ?
后面会通过案例体验!

递归

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

递归的好处:
把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解
小的问题解决, 大的问题也会逐一进行解决

递归解决问题注意事项 :
递归出口:否则会出现内存溢出
递归规则:需要找到与原问题相似的规模较小的问题

File类的创建
/* 绝对路径 : 以盘符开始 相对路径 : 相对于IDEA工具项目下 /public class PathDemo { public static void main(String[] args) throws IOException { //相对路径类的创建 只能表示项目中的文件 File f2 = new File(“day10_demo\a.txt”); System.out.println( f2); File f3 = new File(“day10_demo\b.txt”); System.out.println(f3); //绝对路径类的创建 File f4 = new File(“D:\IDEA_Paper\Java_Employment\day10_demo\b.txt”); System.out.println(“f4 = “ + f4); }}*

File类的创建功能 :
public class FileDemo2 { public static void main(String[] args) throws IOException { //1 public boolean createNewFile() : 创建一个新的空的文件 File f3 = new File(“day10_demo\美女.jpg”); boolean newFile = f3.createNewFile(); System.out.println(“newFile = “ + newFile); //true
//返回boolean值 true 或者false! //第二次输出打印 就是false 文件实际存在 就返回false 文件不会被覆盖! //注意创建文件父目录一定要存在! 否则报错! //2 public boolean mkdir() : 创建一个单级文件夹 //只能创建单级别目录! File f4 = new File(“day10_demo/a1a1”); boolean mkdir = f4.mkdir(); System.out.println(“mkdir = “ + mkdir); //true //3 public boolean mkdirs() : 创建一个多级文件夹 !!! File f5 = new File(“day10_demo\a1\sss”); boolean mkdirs = f5.mkdirs(); System.out.println(“mkdirs = “ + mkdirs); //true }}

File类 删除文件!

public class FileDemo3 {
public static void main(String[] args) {
//删除文件 可以直接删除! File f1 = new File(“day10_demo\美女.jpg”); boolean delete = f1.delete(); System.out.println(“delete = “ + delete); //true
**
========================================**

//删除文件夹没有内容 可以直接删除! _File f2 = new File(“day10_demo\a1a1”);boolean delete1 = f2.delete();System.out.println(“delete1 = “ + delete1); //true =======================================
**
//删除文件夹内有内容 不能直接删除! 会返回false!//需要先做删除文件夹内容的操作! 然后才可以删除空的文件夹!File f3 = new File(“day10_demo\a1”);boolean delete2 = f3.delete();System.out.println(“delete2 = “ + delete2); //false
**
}}

File类的判断和获取功能!

public class FileDemo4 { public static void main(String[] args) { File f1 = new File(“day10_demo\a.txt”); //确实存在文件 File f2 = new File(“day10_demo\a1”); //确实存在的文件夹 File f3 = new File(“day10_demo\xaa.txt”); //不存在的文件! //public boolean isDirectory() 测试此抽象路径名表示的File是否为目录 System.out.println(f1.isDirectory()); //false System.out.println(f2.isDirectory()); //true System.out.println(f3.isDirectory()); //false //public boolean isFile() 测试此抽象路径名表示的File是否为文件 System.out.println(f1.isFile()); //true System.out.println(f2.isFile()); //false System.out.println(f3.isFile()); //false //public boolean exists() 测试此抽象路径名表示的File是否存在 System.out.println(f1.exists()); //true System.out.println(f2.exists()); //true System.out.println(f3.exists()); //false** System.out.println(“===========================”); //public String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串 //绝对路径 System.out.println(f1.getAbsolutePath()); //返回带盘符的路径!** //public String getPath() 获取的是创建File对象给定的路径 System.out.println(f1.getPath()); // 返回你创建对象是给的路径 File后面new里面写什么就返回什么! // 写的是绝对路径是就返回绝对路径 // 写的是相对路径是就返回相对路径 //public String getName()返回由此抽象路径名表示的文件或目录的名称 System.out.println(f1.getName()); //a.txt //会有后缀跟着 因为文件和目录本身就有后缀** }}**

File类高级获取功能 public File[] listFiles() 返回此抽象路径名表示的目录中的文件和目录的File对象数组**

public class FileDemo5 { public static void main(String[] args) { //获取这个文件夹下的所有文件目录! File f1 = new File(“day10_demo\统计文件个数文件夹”); File[] files = f1.listFiles(); for (File file : files) { System.out.println(“file = “ + file); //返回这个存在文件的所有子文件** //只能拿到该文件下的子文件信息—->子文件内的文件不会拿到!
File有重写 toString所有可以直接打印数据出来! //所有子文件夹都会显示 //排序默认是按照建立在文件的字符串长度 然后判断a-z的字母顺序! } System.out.println(“统计文件个数文件夹里的个数有: “ + files.length); System.out.println(“=================”); //没有这个文件 所以返回null File f2 = new File(“day10_demo\333”); File[] files1 = f2.listFiles(); System.out.println(“files1 = “ + files1); //files1= null** System.out.println(“=================”); //有这个文件 但是不能直接获取文件 所以返回null File f3 = new File(“day10_demo\a.txt”); File[] files2 = f3.listFiles(); System.out.println(“files2 = “ + files2); //files2 = null** // 获取空文件夹 File f4 = new File(“day10_demo\nono”); File[] files3 = f4.listFiles(); System.out.println(“files3 = “ + files3 ); //files3 = [Ljava.io.File;@34ce8af7 }}**

统计一个文件夹中每种文件的个数并打印

public class FileTest01 { public static void main(String[] args) { File dir = new File(“day10_demo\统计文件个数文件夹”); Map map = new HashMap<>(); File[] files = dir.listFiles(); //1.遍历文件夹中的所有子文件! for (File file : files) { //2.做一个只要文件的判断! if (file.isFile()) { String name = file.getName(); //按照切割.需要反编译所以前面加俩个// String[] names = name.split(“\.”);//按照点“.“进行切割! String suffix = names[names.length - 1];//防止文件名有.参与 所以获取最后一个元素 //用if做一个统计! if (map.containsKey(suffix)) { //存后面的后缀 Integer count = map.get(suffix);//获取原来的次数! count++; map.put(suffix, count);//将统计到的次数放回map集合! } else { map.put(suffix, 1);//如果没有 那就是第一次出现 从1开始! } } } Set> set = map.entrySet(); for (Map.Entry entry : set) { String key = entry.getKey(); Integer value = entry.getValue(); System.out.println(key + “: “ + value + “ 个!”); } }}**

字节输出流步骤 1 创建字节输出流对象
2 写数据
3 释放资源
public class OutputStreamDemo1 { public static void main(String[] args) throws IOException { //创建流对象!public FileOutputStream(String name) //如果file02.txt不存在 就新创建 如果存在那就会清空数据 将所新写的内容放进去! FileOutputStream fos = new FileOutputStream(“day10_demo/file02.txt”); //写数据! 对应Ascally码表! fos.write(97);//a fos.write(98);//b fos.write(99);//c fos.write(‘A’);//A fos.write(‘B’);//B fos.write(‘C’);//C //关闭(释放)资源! fos.close(); }}
1 void write(int b) 一次写一个字节数据2 void write(byte[] b) 一次写一个字节数组数据3 void write(byte[] b, int off, int len) 一次写一个字节数组的部分数据

public class OutputStreamDemo2 { public static void main(String[] args) throws IOException { //一: 创建字节输出流! FileOutputStream fos = new FileOutputStream(“day10_demo\file02.txt”); // 二: 写数据!** // 1 void write(int b) 一次写一个字节数据 fos.write(‘A’); //2 void write(byte[] b) 一次写一个字节数组数据 byte[] brr = {97, 98, 99, 100, 101};//abcde fos.write(brr); //3 void write(byte[] b, int off, int len) 一次写一个字节数组的部分数据 //off:索引为第3, len:写进去2个! fos.write(brr,3, 2);
byte[] crr = {49, 53, 53, 51, 54, 52, 52, 53, 53, 57, 57};fos.write(crr, 0, 11); 手机号!!!
//关闭资源! fos.close();
} }**

字节流创建txt文件内容之换行!

// windows : \r\n 换行定义为String类型 然后变量名.调用getBytes方法!
直接write就可以!String huanhang = “\r\n”;byte[] newline= huanhang.getBytes();fos.write(newline); //换行定义一次后 可以重复使用!**

文件内容之拼接!
//进行拼接 保留之前的内容 不会在每次执行被覆盖掉!
FileOutputStream fos = new FileOutputStream(“day10_demo\file02.txt”,true);

字节输入流
注意输出流会帮你创建没有的文件,但是输入流不会!

InputStream类 : 字节输入流最顶层的类 , 抽象类

public class FileInputStreamDemo1 { public static void main(String[] args) throws IOException {** // 1 创建字节输入流对象 必须保证文件存在 要不然会报错! 因为输入读取不会创建新文件! FileInputStream fis = new FileInputStream(“day10_demo\file02.txt”);** // 2 读数据 //单个读取fis.read.sout
System.out.println(fis.read());//97 int b; while ( (b=fis.read())!=-1){ System.out.print((char)b); } //3 释放资源 fis.close(); }}**

使用I输入O输出 对文件的复制!

复制文件,其实就把文件的内容从一个文件中读取出来(数据源),然后写入到另一个文件中(目的地)
数据源 : “D:ASCLL码表.png”目的地 : “day10_demo\ASC.png”**

public class FileInputStreamDemo2 { public static void main(String[] args) throws IOException { String src = “D:\AAA\ASCLL码表.png”;//数据源 String dest = “day10_demo\ASCLL码表.png”;//目的地 //创建 输入 输出! FileInputStream fis = new FileInputStream(src); //fis输入数据 FileOutputStream fos = new FileOutputStream(dest);//fos读取数据! int b; while ((b = fis.read()) != -1) {//将字节从源文件中读取到内存中用b变量保存 fos.write(b); } //关闭资源 先开的后关闭 后开的先关闭! fos.close(); fis.close(); }}
整合try关闭资源 不需要手动写重复代码!
public class FileInputStreamDemo3 { public static void main(String[] args) {** String src = “D:\AAA\ASCLL码表.png”;//数据源 String dest = “day10_demo\ASCLL码表.png”;//目的地 //创建 输入 输出! try ( FileInputStream fis = new FileInputStream(src); //fis输入数据 FileOutputStream fos = new FileOutputStream(dest);//fos读取数据! ) { int b; while ((b = fis.read()) != -1) fos.write(b); } catch (IOException e) { e.printStackTrace();//关闭资源 先开的后关闭 后开的先关闭! }} }
字符输入流 字节数组读取内容案例!
public class FileInputStreamDemo5 { public static void main(String[] args) throws IOException {//public String(byte[] bytes, int startIndex, int length) : 把字节数组的一部分转成字符串 try (FileInputStream fis = new FileInputStream(“day10_demo\a.txt”)) {
byte[] buf = new byte[10];
//定义一个数组缓冲区,临时保存每次读取的字节
int len;
//临时保存每次读取的字节个数!
while ((len = fis.read(buf)) != -1) { //将读取的数据 变成字符串! String s = new String(buf, 0, len); System.out.print(s);//helloworldhelloworldhelloworldhelloworldhelloworldhelloworld } } catch (IOException e) { e.printStackTrace(); } }}**

提高拷贝速度案例!
public class FileInputStreamDemo2 { public static void main(String[] args) throws IOException { String src = “D:\AAA\ASCLL码表.png”;//数据源 String dest = “day10_demo\AS表.png”;//目的地** FileInputStream fis = new FileInputStream(src); //fis输入数据 FileOutputStream fos = new FileOutputStream(dest);//fos读取数据! byte[] buf = new byte[8*1024]; int len; while ((len = fis.read(buf)) != -1) {//把读取的有效数据写到数据中 fos.write(buf,0,len); //长度要写读取到的len! } //关闭资源 先开的后关闭 后开的先关闭! fos.close(); fis.close(); }}
package com.itheima.Day10Work;**import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;*/在你计算机的一个盘(比如D盘)根目录下创建一个文件,名字叫做 file01.txt。保存以下内容(要求是单字节字符,比如字母或者数字) file01.txt** abcdef123456 1. 使用字节输入流一次读取一个字节的方法将file01.txt的文件读取并打印 2. 使用字节输入流一次读取多个字节的方法将file01.txt的文件读取并打印/public class Demo01 { public static void main(String[] args) throws IOException { read1(); read2();** } public static void read1() throws IOException {** FileInputStream fis = new FileInputStream(“D:\file01.txt”); int b; while ((b = fis.read()) != -1) { System.out.print((char) b); } fis.close(); } public static void read2() throws IOException { FileInputStream fis = new FileInputStream(“D:\file01.txt”); byte[] bys = new byte[1024]; int len; while ((len = fis.read(bys)) != -1) { System.out.println(new String(bys, 0, len)); }** }}*

package com.itheima.Day10Work;**import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;**//在D盘中创建两个文件夹,img1,img2。在img1中放置一个图片文件,// 将img1中的图片文件使用字节流复制到img2中。public class Demo02 { public static void main(String[] args) throws IOException {** File f1=new File(“D:\img1”); boolean mkdirs1 = f1.mkdirs();** File f2=new File(“D:\img2”); boolean mkdirs = f2.mkdirs(); String src=”D:\img1\A1.png”; String dest=”D:\img2\b1.png “; FileInputStream fis=new FileInputStream(src); FileOutputStream fos = new FileOutputStream( dest); byte[]buf=new byte[81024]; int len; while ((len=fis.read(buf))!=-1){ fos.write(buf,0,len); } fos.close(); fis.close(); }} *

package com.itheima.Day10Work;**import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.util.Arrays;**//```java//登鹳雀楼//王之涣//白日依山尽,//黄河入海流。//欲穷千里目,//更上一层楼。public class Demo03 { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream(“day10_demo\JAVA”, true); byte[] bytes = “登鹳雀楼 王之涣 白日依山尽 黄河入海 流欲穷千里目 更上一层楼”.getBytes(); System.out.println(Arrays.toString(bytes)); fos.write(bytes); fos.close();** }}**

package com.itheima.Day10Work;**import java.io.FileInputStream; import java.io.IOException;//将题目1中文件的诗文使用字符输入流读取并打印到控制台。public class Demo04 { public static void main(String[] args) throws IOException {** try (FileInputStream fis = new FileInputStream(“D:\img1\i1.txt”); ) { byte[] buf = new byte[10]; int len; while ((len =fis.read(buf))!=-1){ String s=new String(buf,0,len); System.out.print(s); } }catch (IOException e){ e.printStackTrace(); } }}**

*/请使用FileWriter向文件输出:HelloWorld
1. 用 try-catch-finally 方式处理异常。
2. 用 try-with-resource 方式处理异常。*/
public class Demo06 {
public static void main(String[] args) throws IOException {
teat01();
test02();
}

  1. public static void teat01() throws IOException {<br /> FileOutputStream fos = null;<br /> try {<br /> fos = new FileOutputStream("day10_demo\\a.txt");<br /> byte[] arr = {'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd'};<br /> fos.write(arr);<br /> String huanhang = "\r\n";<br /> byte[] newline = huanhang.getBytes();<br /> fos.write(newline);<br /> } catch (IOException e) {<br /> e.printStackTrace();<br /> } finally {<br /> try {<br /> if (fos != null) {<br /> fos.close();<br /> }<br /> } catch (IOException e) {<br /> e.printStackTrace();<br /> } } }<br /> //2. 用 `try-with-resource` 方式处理异常<br /> public static void test02() {<br /> FileOutputStream fos = null;<br /> try {<br /> fos = new FileOutputStream("day10_demo\\a.txt");<br /> byte[] arr = {'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd'};<br /> fos.write(arr);<br /> } catch (IOException e) {<br /> e.printStackTrace();<br /> } finally {<br /> try {<br /> fos.close();<br /> } catch (IOException e) {<br /> e.printStackTrace(); } } } }**

load方法 文件中的键值对 读取到内存中!(读取)
注意:Properties文件中的键值对信息必须是一行一个键值对! 否则会认为 (=) 后面都是值!
public class PropertiesDemo3 { public static void main(String[] args) { Properties pro=new Properties(); //文件中的键值对保存到内存中,Propertise对象中! //1.构造一个字节输入流 用来关联文件!就是找文件! try(FileInputStream fis =new FileInputStream(“day11_demo\src\user.properties”) ){ //2.调用load方法,加载数据(读取)! pro.load(fis); //3.打印结构 System.out.println(“pro = “ + pro); }catch (IOException e){ e.printStackTrace(); } }Properties 中的注释用#号键表示!}包名 路径名 模块 包括此类信息都使用英文!

Stors方法 用来保存数据!(写入)

//将内存中的数据保存到硬盘Properties文件下!public class PropertiesDemo3 { public static void main(String[] args) { test02(); } public static void test02(){ Properties pro=new Properties(); pro.setProperty(“username”, “root”); pro.setProperty(“password”, “root”); try(FileOutputStream fos=new FileOutputStream(“day11_demo\db.properties”)){ pro.store(fos,”This is comments 这是注释!”); }catch (IOException e){ e.printStackTrace();** } }

**需求:在properties文件中手动写上姓名和年龄,读取到集合中,将该数据封装成javabean对象 学生!
将文件的信息读取到 控制台 并封装成Student类对象!
public class PropertiesTest {
public static void main(String[] args) {
Properties pro=new Properties();
try (FileInputStream fis=new FileInputStream(“D:\IDEA_Paper\Java_Employment\day11_demo\Student.properties”)){
pro.load(fis);
Student stu = new Student(pro.getProperty(“name”), Integer.parseInt(pro.getProperty(“age”)));
System.out.println(“stu = “ + stu);
}catch (IOException e){
e.printStackTrace();
}
}
}
class Student{····}

将文件的信息读取到控制台
读取以.properties结尾的配置文件(简化写)

public class ResourceBundleDemo { public static void main(String[] args) { //1.获取ResourceBundle 对象,指定src里面的属性文件! ResourceBundle budle = ResourceBundle.getBundle(“iphone”); //2.get String获取键的对应值! String brand = budle.getString(“brand”); System.out.println(“brand = “ + brand); }}

递归 阶乘(方法直接调用自己!)
/*求num的阶层 mian方法中jc(5).var 写几就是求几的阶乘5!=5X4X4X3X2X1 4!=4X3X2X1 3!=3X2X1 2!=2X1 1!=1X1 @param n @parampublic static long jc (int n) { //n!=n(n-1); if(n==1){ return 1; } else { return njc(n-1); } } 把大问题(5)消化为小问题(4)··直到解决完最小问题(1) 所以都解决了!
使用递归删除计算机中指定的文件夹
** public static void deleteFile(File file){
** //对传进来的文件进行判断是否存在
** if(!file.exists()){ //不存在对异常进行捕获 并返回文件不存在
throw new RuntimeException(“文件不存在”); } if(file.isFile()){ file.delete(); //判断如果是文件那就直接删除! System.out.println(“删除文件为: “ + file);
//递归的出口 当某一个子文件没有了子文件夹什么都没有了,递归就结束了! }else { //走到这个说明file是文件夹!删除只能删除空文件夹
// 先把该子文件(包含文件,目录)删除! 那么就要对该文件夹进行遍历!
**
File[] files = file.listFiles(); for (File childFile : files) { deleteFile(childFile); }
** //子文件删除干净后,在删除当前空文件夹!
** file.delete();
System.out.println(“删除文件夹: “ + file);
}
}
}

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

递归的好处 :
把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解小的问题解决 , 大的问题也会逐一进行解决
递归解决问题注意事项 :
递归出口:否则会出现内存溢出
递归规则:需要找到与原问题相似的规模较小的问题

案例1:
需求:用递归求5的阶乘,并把结果在控制台输出 思路: 1 定义一个方法,用于递归求阶乘,参数为一个int类型的变量 2 在方法内部判断该变量的值是否是1 是:返回1 不是:返回n*(n-1)! 3 调用方法 4 输出结果

public class Demo1 {
public static void main(String[] args) {
long jc = jc(5);
System.out.println(“jc = “ + jc);//jc = 120
}
//求n的阶乘
public static long jc(int n){
// n! = n (n-1)
if (n == 1) {
return 1;
} else {
return n
jc (n - 1);
}
}
}

案例2:
需求 : 使用递归删除计算机中指定的文件夹

public class Demo2 {
public static void main(String[] args) {
File file = new File(“D:\桌面\代码开发工具idea”);
deleteFile(file);
}

/* 删除文件或者文件夹
@param file 要删除的文件
/
public static void deleteFile(File file){
//判断文件是否存在
if (!file.exists()) {
throw new RuntimeException(“文件不存在!非法操作”);
}
if (file.isFile()) {
file.delete();//文件可以直接删
System.out.println(“成功删除文件” + file);
//递归的出口:当某一个子文件夹没有了子文件 递归结束
} else {
//file 是文件夹 ,删除只能删除空的文件夹
//先把子文件(包括文件,目录)先删除
File[] files = file.listFiles();
for (File childFile : files) {
deleteFile(childFile);//
}
//子文件删除干净后,再删除当前空文件夹
file.delete();
System.out.println(“成功删除文件夹” + file);
}
}
}

Properties概述:

是一个Map体系的集合类
Properties中有跟IO相关的方法
不需要加泛型.默认存储的是Object类型, 但是工作中只存字符串

1.Properties作为集合的特有方法
Object setProperty(String key, String value) 设置集合的键和值,都是String类型,相当于put方法
String getProperty(String key) 使用此属性列表中指定的键搜索属性 , 相当于get方法
Set stringPropertyNames() 从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串 , 相当于keySet方法

  1. public class PropertiesDemo2 {
  2. public static void main(String[] args) {
  3. Properties pro = new Properties();
  4. //存数据
  5. pro.setProperty("username" , "root");//相当于put方法
  6. pro.setProperty("password" , "1223");
  7. System.out.println("pro = " + pro);
  8. //输出 : pro = {password=1223, username=root}
  9. //获取数据
  10. String username = pro.getProperty("username");//相当于get方法
  11. System.out.println("username = " + username);
  12. //输出 : username = root
  13. //获取所有键的值
  14. Set<String> names = pro.stringPropertyNames();//相当于keySet方法
  15. System.out.println("names = " + names);
  16. //输出 : names = [password, username]
  17. }
  18. }

2 和 IO 流结合的方法
void load(InputStream inStream) : 以字节流形式 , 把文件中的键值对, 读取到集合中
void load(Reader reader) 以字符流形式 , 把文件中的键值对, 读取到集合中
void store(OutputStream out, String comments) 把集合中的键值对,以字节流形式写入文件中 , 参数二为注释
void store(Writer writer, String comments) 把集合中的键值对,以字符流形式写入文件中 , 参数二为注释
load负责把文件的键值对读取到集合中 store负责把集合中的键值对写入文件中

  1. public class PropertiesDemo3 {
  2. public static void main(String[] args) {
  3. Properties pro = new Properties();
  4. System.out.println("pro = " + pro);
  5. //文件中的键值对保存到内存中Properties对象中
  6. //1. 构建一个字节输入流关联文件
  7. try(
  8. FileInputStream fis = new FileInputStream("day11_demo/src/user.properties")
  9. ) {
  10. //2.调用load方法加载数据
  11. //username=zhangsan
  12. //password=123456
  13. pro.load(fis);
  14. //3 . 打印结果
  15. //pro = {}
  16. //pro = {password=123456, username=zhangsan}
  17. System.out.println("pro = " + pro);
  18. } catch (IOException e) {
  19. e.printStackTrace();
  20. }
  21. }
  22. }

案例:
需求:在properties文件中手动写上姓名和年龄,读取到集合中,将该数据封装成javabean对象
步骤:
1.将姓名和年龄手动保存在本地properties文件中
2.读取本地properties文件中的数据

  1. public class PropertiesTest {
  2. public static void main(String[] args) {
  3. Properties pro = new Properties();
  4. try(
  5. FileInputStream fis = new FileInputStream("day11_demo/studdent.properties")
  6. ) {
  7. //调用load方法加载数据
  8. pro.load(fis);
  9. System.out.println("pro = " + pro);
  10. //将内存中的name和age 转换为学生对象
  11. Student stu = new Student(pro.getProperty("name"), Integer.parseInt(pro.getProperty("age")));
  12. System.out.println("stu = " + stu);
  13. } catch (IOException e) {
  14. e.printStackTrace();
  15. }
  16. }
  17. }
  18. class Student {
  19. String name;
  20. int age;
  21. public Student(String name, int age) {
  22. this.name = name;
  23. this.age = age;
  24. }
  25. @Override
  26. public String toString() {
  27. return "Student{" +
  28. "name='" + name + '\'' +
  29. ", age=" + age +
  30. '}';
  31. }
  32. }

ResourceBundle工具类

API介绍
java.util.ResourceBundle它是一个抽象类
我们可以使用它的子类PropertyResourceBundle来读取以.properties结尾的配置文件
>通过静态方法直接获取对象
static ResourceBundle getBundle (String baseName) 可以根据名字直接获取默认语言环境下的属性资源。
参数注意: baseName
1.属性集名称不含扩展名。
2.属性集文件是在src目录中的
比如:src中存在一个文件 user.properties
ResourceBundle bundle = ResourceBundle.getBundle(“user”);
>ResourceBundle中常用方法:
String getString(String key) : 通过键,获取对应的值

优点 : 快速读取属性文件的值
需求 :
通过ResourceBundle工具类
将一个属性文件 放到src目录中,使用ResourceBundle去获取键值对数据

  1. public class ResourceBundleDemo {
  2. public static void main(String[] args) {
  3. //1.获取ResourceBundle对象,指定src里面的属性文件
  4. ResourceBundle bundle = ResourceBundle.getBundle("iphone");
  5. //2.getString获取键对应的值
  6. String brand = bundle.getString("brand");
  7. System.out.println("brand = " + brand);//brand = HUAWEI Mate40RS
  8. }
  9. }

day11-IO流,Properties集合,IO工具类

今日目标

  • IO流的介绍
  • IO流的分类
  • 字节输出流
  • 字节输入流
  • 字节缓冲区流
  • Properties集合

1 IO流的介绍

1.1 为什么要学习IO流

  • 通过变量,数组,或者集合存储数据
    • 都是不能永久化存储 , 因为数据都是存储在内存中
    • 只要代码运行结束,所有数据都会丢失
  • 使用IO流
    • 1,将数据写到文件中,实现数据永久化存储
    • 2,把文件中的数据读取到内存中(Java程序)

1.2 什么是IO流

  • I 表示intput ,是数据从硬盘进内存的过程,称之为读。
  • O 表示output ,是数据从内存到硬盘的过程。称之为写
  • IO的数据传输,可以看做是一种数据的流动,按照流动的方向,以内存为参照物,进行读写操作
    • 简单来说:内存在读,内存在写

1.3 IO流的分类

  • 按照流向区分
    • 输入流 : 用来读数据
    • 输出流 : 用来写数据
  • 按照类型区分
    • 字节流
    • 字符流
  • 注意 :
    • 字节流可以操作任意文件
    • 字符流只能操作纯文本文件
    • 用windows记事本打开能读的懂,那么这样的文件就是纯文本文件。

2 字节流输出流

2.1 字节输出流入门

  • FileOutputStream类 :
    • OutputStream有很多子类,我们从最简单的一个子类开始。
    • java.io.FileOutputStream类是文件输出流,用于将数据写出到文件
  • 构造方法 :
    • public FileOutputStream(File file):创建文件输出流以写入由指定的 File对象表示的文件。
    • public FileOutputStream(String name): 创建文件输出流以指定的名称写入文件。

      1. public class FileOutputStreamConstructor throws IOException {
      2. public static void main(String[] args) {
      3. // 使用File对象创建流对象
      4. File file = new File("a.txt");
      5. FileOutputStream fos = new FileOutputStream(file);
      6. // 使用文件名称创建流对象
      7. FileOutputStream fos = new FileOutputStream("b.txt");
      8. }
      9. }
  • 字节输出流写数据快速入门
    • 创建字节输出流对象。
    • 写数据
    • 释放资源 ```java package com.itheima.outputstream_demo;

import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException;

/ 字节输出流写数据快速入门 : 1 创建字节输出流对象。 2 写数据 3 释放资源 / public class OutputStreamDemo1 { public static void main(String[] args) throws IOException { // 创建字节输出流对象 // 如果指定的文件不存在 , 会自动创建文件 // 如果文件存在 , 会把文件中的内容清空 FileOutputStream fos = new FileOutputStream(“day11_demo\a.txt”);

  1. // 写数据
  2. // 写到文件中就是以字节形式存在的
  3. // 只是文件帮我们把字节翻译成了对应的字符 , 方便查看
  4. fos.write(97);
  5. fos.write(98);
  6. fos.write(99);
  7. // 释放资源
  8. // while(true){}
  9. // 断开流与文件中间的关系
  10. fos.close();
  11. }

}

  1. <a name="a913834a"></a>
  2. ### 2.2 字节输出流写数据的方法
  3. - 字节流写数据的方法
  4. - 1 void write(int b) 一次写一个字节数据
  5. - 2 void write(byte[] b) 一次写一个字节数组数据
  6. - 3 void write(byte[] b, int off, int len) 一次写一个字节数组的部分数据
  7. ```java
  8. package com.itheima.outputstream_demo;
  9. import java.io.FileNotFoundException;
  10. import java.io.FileOutputStream;
  11. import java.io.IOException;
  12. /*
  13. 字节流写数据的3种方式
  14. 1 void write(int b) 一次写一个字节数据
  15. 2 void write(byte[] b) 一次写一个字节数组数据
  16. 3 void write(byte[] b, int off, int len) 一次写一个字节数组的部分数据
  17. */
  18. public class OutputStreamDemo2 {
  19. public static void main(String[] args) throws IOException {
  20. // 创建字节输出流对象
  21. FileOutputStream fos = new FileOutputStream("day11_demo\\a.txt");
  22. // 写数据
  23. // 1 void write(int b) 一次写一个字节数据
  24. fos.write(97);
  25. fos.write(98);
  26. fos.write(99);
  27. // 2 void write(byte[] b) 一次写一个字节数组数据
  28. byte[] bys = {65, 66, 67, 68, 69};
  29. fos.write(bys);
  30. // 3 void write(byte[] b, int off, int len) 一次写一个字节数组的部分数据
  31. fos.write(bys, 0, 3);
  32. // 释放资源
  33. fos.close();
  34. }
  35. }

2.3 写数据的换行和追加写入

  1. package com.itheima.outputstream_demo;
  2. import java.io.FileOutputStream;
  3. import java.io.IOException;
  4. /*
  5. 字节流写数据的换行和追加写入
  6. 1 字节流写数据如何实现换行呢?
  7. 写完数据后,加换行符
  8. windows : \r\n
  9. linux : \n
  10. mac : \r
  11. 2 字节流写数据如何实现追加写入呢?
  12. 通过构造方法 : public FileOutputStream(String name,boolean append)
  13. 创建文件输出流以指定的名称写入文件。如果第二个参数为true ,不会清空文件里面的内容
  14. */
  15. public class OutputStreamDemo3 {
  16. public static void main(String[] args) throws IOException {
  17. // 创建字节输出流对象
  18. FileOutputStream fos = new FileOutputStream("day11_demo\\a.txt");
  19. // void write(int b) 一次写一个字节数据
  20. fos.write(97);
  21. // 因为字节流无法写入一个字符串 , 把字符串转成字节数组写入
  22. fos.write("\r\n".getBytes());
  23. fos.write(98);
  24. fos.write("\r\n".getBytes());
  25. fos.write(99);
  26. fos.write("\r\n".getBytes());
  27. // 释放资源
  28. fos.close();
  29. }
  30. }
  1. package com.itheima.outputstream_demo;
  2. import java.io.FileOutputStream;
  3. import java.io.IOException;
  4. /*
  5. 字节流写数据的换行和追加写入
  6. 1 字节流写数据如何实现换行呢?
  7. 写完数据后,加换行符
  8. windows : \r\n
  9. linux : \n
  10. mac : \r
  11. 2 字节流写数据如何实现追加写入呢?
  12. 通过构造方法 : public FileOutputStream(String name,boolean append)
  13. 创建文件输出流以指定的名称写入文件。如果第二个参数为true ,不会清空文件里面的内容
  14. */
  15. public class OutputStreamDemo3 {
  16. public static void main(String[] args) throws IOException {
  17. // 创建字节输出流对象
  18. // 追加写数据
  19. // 通过构造方法 : public FileOutputStream(String name,boolean append) : 追加写数据
  20. FileOutputStream fos = new FileOutputStream("day11_demo\\a.txt" , true);
  21. // void write(int b) 一次写一个字节数据
  22. fos.write(97);
  23. // 因为字节流无法写入一个字符串 , 把字符串转成字节数组写入
  24. fos.write("\r\n".getBytes());
  25. fos.write(98);
  26. fos.write("\r\n".getBytes());
  27. fos.write(99);
  28. fos.write("\r\n".getBytes());
  29. // 释放资源
  30. fos.close();
  31. }
  32. // 写完数据换行操作
  33. private static void method1() throws IOException {
  34. // 创建字节输出流对象
  35. FileOutputStream fos = new FileOutputStream("day11_demo\\a.txt");
  36. // void write(int b) 一次写一个字节数据
  37. fos.write(97);
  38. // 因为字节流无法写入一个字符串 , 把字符串转成字节数组写入
  39. fos.write("\r\n".getBytes());
  40. fos.write(98);
  41. fos.write("\r\n".getBytes());
  42. fos.write(99);
  43. fos.write("\r\n".getBytes());
  44. // 释放资源
  45. fos.close();
  46. }
  47. }

3 字节输入流

3.1 字节输入流介绍

  • 字节输入流类
    • InputStream类 : 字节输入流最顶层的类 , 抽象类
      —- FileInputStream类 : FileInputStream extends InputStream
  • 构造方法
    • public FileInputStream(File file) : 从file类型的路径中读取数据
    • public FileInputStream(String name) : 从字符串路径中读取数据
  • 步骤
    • 创建输入流对象
    • 读数据
    • 释放资源
  • ``` package com.itheima.inputstream_demo;

import java.io.FileInputStream; import java.io.IOException;

/ 字节输入流写数据快速入门 : 一次读一个字节 第一部分 : 字节输入流类 InputStream类 : 字节输入流最顶层的类 , 抽象类 —- FileInputStream类 : FileInputStream extends InputStream 第二部分 : 构造方法 public FileInputStream(File file) : 从file类型的路径中读取数据 public FileInputStream(String name) : 从字符串路径中读取数据 第三部分 : 字节输入流步骤 1 创建输入流对象 2 读数据 3 释放资源 / public class FileInputStreamDemo1 { public static void main(String[] args) throws IOException { // 创建字节输入流对象 // 读取的文件必须存在 , 不存在则报错 FileInputStream fis = new FileInputStream(“day11_demo\a.txt”);

  1. // 读数据 , 从文件中读到一个字节
  2. // 返回的是一个int类型的字节
  3. // 如果想看字符, 需要强转
  4. int by = fis.read();
  5. System.out.println((char) by);
  6. // 释放资源
  7. fis.close();
  8. }

}

  1. <a name="e864e190"></a>
  2. ### 3.2 字节输入流读多个字节

package com.itheima.inputstream_demo;

import java.io.FileInputStream; import java.io.IOException;

/ 字节输入流写数据快速入门 : 读多个字节 第一部分 : 字节输入流类 InputStream类 : 字节输入流最顶层的类 , 抽象类 —- FileInputStream类 : FileInputStream extends InputStream 第二部分 : 构造方法 public FileInputStream(File file) : 从file类型的路径中读取数据 public FileInputStream(String name) : 从字符串路径中读取数据 第三部分 : 字节输入流步骤 1 创建输入流对象 2 读数据 3 释放资源 / public class FileInputStreamDemo2 { public static void main(String[] args) throws IOException { // 创建字节输入流对象 // 读取的文件必须存在 , 不存在则报错 FileInputStream fis = new FileInputStream(“day11_demo\a.txt”);

  1. // 读数据 , 从文件中读到一个字节
  2. // 返回的是一个int类型的字节
  3. // 如果想看字符, 需要强转

// int by = fis.read(); // System.out.println(by); // by = fis.read(); // System.out.println(by); // by = fis.read(); // System.out.println(by); // // by = fis.read(); // System.out.println(by); // by = fis.read(); // System.out.println(by); // by = fis.read(); // System.out.println(by);

  1. // 循环改进
  2. int by;// 记录每次读到的字节
  3. while ((by = fis.read()) != -1) {
  4. System.out.print((char) by);
  5. }
  6. // 释放资源
  7. fis.close();
  8. }

}

  1. <a name="d50d6463"></a>
  2. ### 3.3 图片的拷贝
  3. ```java
  4. package com.itheima.inputstream_demo;
  5. import java.io.FileInputStream;
  6. import java.io.FileNotFoundException;
  7. import java.io.FileOutputStream;
  8. import java.io.IOException;
  9. /*
  10. 需求 : 把 "图片路径\xxx.jpg" 复制到当前模块下
  11. 分析:
  12. 复制文件,其实就把文件的内容从一个文件中读取出来(数据源),然后写入到另一个文件中(目的地)
  13. 数据源:
  14. xxx.jpg --- 读数据 --- FileInputStream
  15. 目的地:
  16. 模块名称\copy.jpg --- 写数据 --- FileOutputStream
  17. */
  18. public class FileInputStreamDemo2 {
  19. public static void main(String[] args) throws IOException {
  20. // 创建字节输入流对象
  21. FileInputStream fis = new FileInputStream("D:\\传智播客\\安装包\\好看的图片\\liqin.jpg");
  22. // 创建字节输出流
  23. FileOutputStream fos = new FileOutputStream("day11_demo\\copy.jpg");
  24. // 一次读写一个字节
  25. int by;
  26. while ((by = fis.read()) != -1) {
  27. fos.write(by);
  28. }
  29. // 释放资源
  30. fis.close();
  31. fos.close();
  32. }
  33. }

3.4 异常的捕获处理

  • JDK7版本之前处理方式 : 手动释放资源
    ```java package com.itheima.inputstream_demo;

import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException;

/ 需求 : 对上一个赋值图片的代码进行使用捕获方式处理 / public class FileInputStreamDemo4 { public static void main(String[] args) { FileInputStream fis = null ; FileOutputStream fos = null; try { // 创建字节输入流对象 fis = new FileInputStream(“D:\传智播客\安装包\好看的图片\liqin.jpg”);

  1. // 创建字节输出流
  2. fos = new FileOutputStream("day11_demo\\copy.jpg");
  3. // 一次读写一个字节
  4. int by;
  5. while ((by = fis.read()) != -1) {
  6. fos.write(by);
  7. }
  8. } catch (IOException e) {
  9. e.printStackTrace();
  10. } finally {
  11. // 释放资源
  12. if(fis != null){
  13. try {
  14. fis.close();
  15. } catch (IOException e) {
  16. e.printStackTrace();
  17. }
  18. }
  19. // 释放资源
  20. if(fos != null){
  21. try {
  22. fos.close();
  23. } catch (IOException e) {
  24. e.printStackTrace();
  25. }
  26. }
  27. }
  28. }

}

  1. -
  2. <a name="441e4fbd"></a>
  3. ##### JDK7版本优化处理方式 : 自动释放资源
  4. - JDK7优化后可以使用 try-with-resource 语句 , 该语句确保了每个资源在语句结束时自动关闭。<br />简单理解 : 使用此语句,会自动释放资源 , 不需要自己在写finally代码块了
  5. - 格式 :
  6. ```java
  7. 格式 :
  8. try (创建流对象语句1 ; 创建流对象语句2 ...) {
  9. // 读写数据
  10. } catch (IOException e) {
  11. 处理异常的代码...
  12. }
  13. 举例 :
  14. try (
  15. FileInputStream fis1 = new FileInputStream("day11_demo\\a.txt") ;
  16. FileInputStream fis2 = new FileInputStream("day11_demo\\b.txt") )
  17. {
  18. // 读写数据
  19. } catch (IOException e) {
  20. 处理异常的代码...
  21. }
  • 代码实践
    ```java package com.itheima.inputstream_demo;

import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException;

/* JDK7版本优化处理方式

  1. 需求 : 对上一个赋值图片的代码进行使用捕获方式处理

*/ public class FileInputStreamDemo5 { public static void main(String[] args) { try ( // 创建字节输入流对象 FileInputStream fis = new FileInputStream(“D:\传智播客\安装包\好看的图片\liqin.jpg”); // 创建字节输出流 FileOutputStream fos = new FileOutputStream(“day11_demo\copy.jpg”) ) { // 一次读写一个字节 int by; while ((by = fis.read()) != -1) { fos.write(by); } // 释放资源 , 发现已经灰色 , 提示多余的代码 , 所以使用 try-with-resource 方式会自动关流 // fis.close(); // fos.close(); } catch (IOException e) { e.printStackTrace(); } } }

  1. <a name="a23881ff"></a>
  2. ### 3.4 字节输入流一次读一个字节数组
  3. - FileInputStream类 :
  4. - public int read(byte[] b) : 从输入流读取最多b.length个字节的数据, 返回的是真实读到的数据个数
  5. ```java
  6. package com.itheima.inputstream_demo;
  7. import javax.sound.midi.Soundbank;
  8. import java.io.FileInputStream;
  9. import java.io.FileNotFoundException;
  10. import java.io.IOException;
  11. /*
  12. FileInputStream类 :
  13. public int read(byte[] b):
  14. 1 从输入流读取最多b.length个字节的数据
  15. 2 返回的是真实读到的数据个数
  16. */
  17. public class FileInputStreamDemo6 {
  18. public static void main(String[] args) throws IOException {
  19. // 创建字节输入流对象
  20. FileInputStream fis = new FileInputStream("day11_demo\\a.txt");
  21. // public int read(byte[] b):
  22. // 1 从输入流读取最多b.length个字节的数据
  23. // 2 返回的是真实读到的数据个数
  24. byte[] bys = new byte[3];
  25. // int len = fis.read(bys);
  26. // System.out.println(len);// 3
  27. // System.out.println(new String(bys));// abc
  28. //
  29. // len = fis.read(bys);
  30. // System.out.println(len);// 2
  31. // System.out.println(new String(bys));// efc
  32. System.out.println("==========代码改进===============");
  33. // int len = fis.read(bys);
  34. // System.out.println(len);// 3
  35. // System.out.println(new String(bys, 0, len));// abc
  36. //
  37. // len = fis.read(bys);
  38. // System.out.println(len);// 2
  39. // System.out.println(new String(bys, 0, len));// ef
  40. System.out.println("==========代码改进===============");
  41. int len;
  42. while ((len = fis.read(bys)) != -1) {
  43. System.out.print(new String(bys , 0 , len));
  44. }
  45. fis.close();
  46. }
  47. }
  • 对复制图片的代码进行使用一次读写一个字节数组的方式进行改进
    ```java package com.itheima.inputstream_demo;

import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException;

/* 需求 : 对复制图片的代码进行使用一次读写一个字节数组的方式进行改进

  1. FileInputStream :
  2. public int read(byte[] b):
  3. 1 从输入流读取最多b.length个字节的数据
  4. 2 返回的是真实读到的数据个数

*/ public class FileInputStreamDemo7 { public static void main(String[] args) throws IOException { // 创建字节输入流对象 FileInputStream fis = new FileInputStream(“D:\传智播客\安装包\好看的图片\liqin.jpg”); // 创建字节输出流 FileOutputStream fos = new FileOutputStream(“day11_demo\copy.jpg”);

  1. byte[] bys = new byte[1024];
  2. int len;// 每次真实读到数据的个数
  3. int by;
  4. while ((len = fis.read(bys)) != -1) {
  5. fos.write(bys, 0, len);
  6. }
  7. // 释放资源
  8. fis.close();
  9. fos.close();
  10. }

}

  1. <a name="4509e786"></a>
  2. ## 4 字节缓冲区流
  3. <a name="70d88e23"></a>
  4. ### 4.1 字节缓冲流概述
  5. - 字节缓冲流:
  6. - BufferOutputStream:缓冲输出流
  7. - BufferedInputStream:缓冲输入流
  8. - 构造方法:
  9. - 字节缓冲输出流:BufferedOutputStream(OutputStream out)
  10. - 字节缓冲输入流:BufferedInputStream(InputStream in)
  11. - 为什么构造方法需要的是字节流,而不是具体的文件或者路径呢?
  12. - 字节缓冲流仅仅提供缓冲区,不具备读写功能 , 而真正的读写数据还得依靠基本的字节流对象进行操作
  13. <a name="40a3f301"></a>
  14. ### 4.2 字节缓冲流案例
  15. ```java
  16. package com.itheima.bufferedstream_demo;
  17. import java.io.*;
  18. /*
  19. 字节缓冲流:
  20. BufferOutputStream:缓冲输出流
  21. BufferedInputStream:缓冲输入流
  22. 构造方法:
  23. 字节缓冲输出流:BufferedOutputStream(OutputStream out)
  24. 字节缓冲输入流:BufferedInputStream(InputStream in)
  25. 为什么构造方法需要的是字节流,而不是具体的文件或者路径呢?
  26. 字节缓冲流仅仅提供缓冲区,不具备读写功能 , 而真正的读写数据还得依靠基本的字节流对象进行操作
  27. 需求 : 使用缓冲流进行复制文件
  28. */
  29. public class BufferedStreamDemo1 {
  30. public static void main(String[] args) throws IOException {
  31. // 创建高效的字节输入流对象
  32. // 在底层会创建一个长度为8192的数组
  33. BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\传智播客\\安装包\\好看的图片\\liqin.jpg"));
  34. // 创建高效的字节输出流
  35. // 在底层会创建一个长度为8192的数组
  36. BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("day11_demo\\copy.jpg"));
  37. // 使用高效流 , 一次读写一个字节
  38. int by;
  39. while ((by = bis.read()) != -1) {
  40. bos.write(by);
  41. }
  42. // byte[] bys = new byte[1024];
  43. // int len;// 每次真实读到数据的个数
  44. // while ((len = bis.read(bys)) != -1) {
  45. // bos.write(bys, 0, len);
  46. // }
  47. // 释放资源
  48. // 在底层会把基本的流进行关闭
  49. bis.close();
  50. bos.close();
  51. }
  52. }

4.3 缓冲流一次读写一个字节原理

image.png

4.4 缓冲流一次读写一个字节数组原理

image.png

  • 四种方式复制视频文件
  1. package com.itheima.bufferedstream_demo;
  2. import java.awt.image.DataBufferDouble;
  3. import java.io.*;
  4. /*
  5. 需求:把“xxx.avi”复制到模块目录下的“copy.avi” , 使用四种复制文件的方式 , 打印所花费的时间
  6. 四种方式:
  7. 1 基本的字节流一次读写一个字节 : 花费的时间为:196662毫秒
  8. 2 基本的字节流一次读写一个字节数组 : 花费的时间为:383毫秒
  9. 3 缓冲流一次读写一个字节 : 花费的时间为:365毫秒
  10. 4 缓冲流一次读写一个字节数组 : 花费的时间为:108毫秒
  11. 分析 :
  12. 数据源 : "D:\a.wmv"
  13. 目的地 : "day11_demo\copy.wmv"
  14. */
  15. public class BufferedStreamDemo2 {
  16. public static void main(String[] args) throws IOException {
  17. long startTime = System.currentTimeMillis();
  18. // method1();
  19. // method2();
  20. // method3();
  21. method4();
  22. long endTime = System.currentTimeMillis();
  23. System.out.println("花费的时间为:" + (endTime - startTime) + "毫秒");
  24. }
  25. // 4 缓冲流一次读写一个字节数组
  26. private static void method4() throws IOException {
  27. // 创建高效的字节输入流
  28. BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\a.wmv"));
  29. // 创建高效的字节输出流
  30. BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("day11_demo\\copy.wmv"));
  31. // 一次读写一个字节数组
  32. byte[] bys = new byte[1024];
  33. int len;// 每次真实读到数据的个数
  34. while ((len = bis.read(bys)) != -1) {
  35. bos.write(bys, 0, len);
  36. }
  37. // 释放资源
  38. bis.close();
  39. bos.close();
  40. }
  41. // 3 缓冲流一次读写一个字节
  42. private static void method3() throws IOException {
  43. // 创建高效的字节输入流
  44. BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\a.wmv"));
  45. // 创建高效的字节输出流
  46. BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("day11_demo\\copy.wmv"));
  47. // 一次读写一个字节
  48. int by;
  49. while ((by = bis.read()) != -1) {
  50. bos.write(by);
  51. }
  52. // 释放资源
  53. bis.close();
  54. bos.close();
  55. }
  56. // 2 基本的字节流一次读写一个字节数组
  57. private static void method2() throws IOException {
  58. // 创建基本的字节输入流对象
  59. FileInputStream fis = new FileInputStream("D:\\a.wmv");
  60. // 创建基本的字节输出流对象
  61. FileOutputStream fos = new FileOutputStream("day11_demo\\copy.wmv");
  62. // 一次读写一个字节数组
  63. byte[] bys = new byte[1024];
  64. int len;// 每次真实读到数据的个数
  65. while ((len = fis.read(bys)) != -1) {
  66. fos.write(bys, 0, len);
  67. }
  68. // 释放资源
  69. fis.close();
  70. fos.close();
  71. }
  72. // 1 基本的字节流一次读写一个字节
  73. private static void method1() throws IOException {
  74. // 创建基本的字节输入流对象
  75. FileInputStream fis = new FileInputStream("D:\\a.wmv");
  76. // 创建基本的字节输出流对象
  77. FileOutputStream fos = new FileOutputStream("day11_demo\\copy.wmv");
  78. // 一次读写一个字节
  79. int by;
  80. while ((by = fis.read()) != -1) {
  81. fos.write(by);
  82. }
  83. // 释放资源
  84. fis.close();
  85. fos.close();
  86. }
  87. }

5.1 Properties集合的概述

  • properties是一个Map体系的集合类
    • public class Properties extends Hashtable <Object,Object>
  • 为什么在IO流部分学习Properties
    • Properties中有跟IO相关的方法
  • 当做双列集合使用
    • 不需要加泛型 , 工作中只存字符串 ```java package com.itheima.properties_demo;

import java.util.Map; import java.util.Properties; import java.util.Set;

/* 1 properties是一个Map体系的集合类

  1. - `public class Properties extends Hashtable <Object,Object>`
  2. 2 为什么在IO流部分学习Properties
  3. - Properties中有跟IO相关的方法
  4. 3 当做双列集合使用
  5. - 不需要加泛型 , 工作中只存字符串

*/ public class PropertiesDemo1 { public static void main(String[] args) { // 创建集合对象 Properties properties = new Properties();

  1. // 添加元素
  2. properties.put("it001" , "张三");
  3. properties.put("it002" , "李四");
  4. properties.put("it003" , "王五");
  5. // 遍历集合 : 键找值
  6. Set<Object> set = properties.keySet();
  7. for (Object key : set) {
  8. System.out.println(key + "---" + properties.get(key));
  9. }
  10. System.out.println("========================");
  11. // 遍历集合 : 获取对对象集合 , 获取键和值
  12. Set<Map.Entry<Object, Object>> set2 = properties.entrySet();
  13. for (Map.Entry<Object, Object> entry : set2) {
  14. Object key = entry.getKey();
  15. Object value = entry.getValue();
  16. System.out.println(key + "---" + value);
  17. }
  18. }

}

  1. <a name="a9badacc"></a>
  2. ### 5.2 Properties作为集合的特有方法
  3. - Object setProperty(String key, String value) 设置集合的键和值,都是String类型,相当于put方法
  4. - String getProperty(String key) 使用此属性列表中指定的键搜索属性 , 相当于get方法
  5. - Set stringPropertyNames() 从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串 , 相当于keySet方法
  6. ```java
  7. package com.itheima.properties_demo;
  8. import java.util.Properties;
  9. import java.util.Set;
  10. /*
  11. Properties作为集合的特有方法
  12. Object setProperty(String key, String value) 设置集合的键和值,都是String类型,相当于put方法
  13. String getProperty(String key) 使用此属性列表中指定的键搜索属性 , 相当于get方法
  14. Set<String> stringPropertyNames() 从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串 , 相当于keySet方法
  15. */
  16. public class PropertiesDemo2 {
  17. public static void main(String[] args) {
  18. // 创建集合对象
  19. Properties properties = new Properties();
  20. // 添加元素
  21. properties.setProperty("it001", "张三");
  22. properties.setProperty("it002", "李四");
  23. properties.setProperty("it003", "王五");
  24. // 遍历集合 : 键找值
  25. Set<String> set = properties.stringPropertyNames();
  26. for (String key : set) {
  27. System.out.println(key + "---" + properties.getProperty(key));
  28. }
  29. }
  30. }

5.3 properties中和IO相关的方法

  • void load(InputStream inStream) 以字节流形式 , 把文件中的键值对, 读取到集合中
  • void load(Reader reader) 以字符流形式 , 把文件中的键值对, 读取到集合中
  • void store(OutputStream out, String comments) 把集合中的键值对,以字节流形式写入文件中 , 参数二为注释
  • void store(Writer writer, String comments) 把集合中的键值对,以字符流形式写入文件中 , 参数二为注释
  1. package com.itheima.properties_demo;
  2. import java.io.FileInputStream;
  3. import java.io.IOException;
  4. import java.util.Properties;
  5. /*
  6. Properties和IO流结合的方法
  7. void load(InputStream inStream) 以字节流形式 , 把文件中的键值对, 读取到集合中
  8. //void load(Reader reader) 以字符流形式 , 把文件中的键值对, 读取到集合中
  9. void store(OutputStream out, String comments) 把集合中的键值对,以字节流形式写入文件中 , 参数二为注释
  10. //void store(Writer writer, String comments) 把集合中的键值对,以字符流形式写入文件中 , 参数二为注释
  11. */
  12. public class PropertiesDemo3 {
  13. public static void main(String[] args) throws IOException {
  14. // 创建Properties集合对象
  15. Properties properties = new Properties();
  16. // void load(InputStream inStream) 以字节流形式 , 把文件中的键值对, 读取到集合中
  17. properties.load(new FileInputStream("day11_demo\\prop.properties"));
  18. // 打印集合中的数据
  19. System.out.println(properties);
  20. }
  21. }
  1. package com.itheima.properties_demo;
  2. import java.io.FileInputStream;
  3. import java.io.FileOutputStream;
  4. import java.io.IOException;
  5. import java.util.Properties;
  6. /*
  7. Properties和IO流结合的方法
  8. void load(InputStream inStream) 以字节流形式 , 把文件中的键值对, 读取到集合中
  9. //void load(Reader reader) 以字符流形式 , 把文件中的键值对, 读取到集合中
  10. void store(OutputStream out, String comments) 把集合中的键值对,以字节流形式写入文件中 , 参数二为注释
  11. //void store(Writer writer, String comments) 把集合中的键值对,以字符流形式写入文件中 , 参数二为注释
  12. */
  13. public class PropertiesDemo3 {
  14. public static void main(String[] args) throws IOException {
  15. Properties properties = new Properties();
  16. properties.setProperty("zhangsan" , "23");
  17. properties.setProperty("lisi" , "24");
  18. properties.setProperty("wangwu" , "25");
  19. properties.store(new FileOutputStream("day11_demo\\prop2.properties") , "userMessage");
  20. }
  21. private static void method1() throws IOException {
  22. // 创建Properties集合对象
  23. Properties properties = new Properties();
  24. // void load(InputStream inStream) 以字节流形式 , 把文件中的键值对, 读取到集合中
  25. properties.load(new FileInputStream("day11_demo\\prop.properties"));
  26. // 打印集合中的数据
  27. System.out.println(properties);
  28. }
  29. }

6 ResourceBundle加载属性文件

学习目标

  • 能够熟练使用ResourceBundle工具类快速读取属性文件的值

内容讲解

【1】API介绍

java.util.ResourceBundle它是一个抽象类,我们可以使用它的子类PropertyResourceBundle来读取以.properties结尾的配置文件。

通过静态方法直接获取对象:
  1. static ResourceBundle getBundle(String baseName) 可以根据名字直接获取默认语言环境下的属性资源。
  2. 参数注意: baseName
  3. 1.属性集名称不含扩展名。
  4. 2.属性集文件是在src目录中的
  5. 比如:src中存在一个文件 user.properties
  6. ResourceBundle bundle = ResourceBundle.getBundle("user");

ResourceBundle中常用方法:

  1. String getString(String key) : 通过键,获取对应的值

【2】代码实践

通过ResourceBundle工具类

将一个属性文件 放到src目录中,使用ResourceBundle去获取键值对数据

  1. package com.itheima.resourcebundle_demo;
  2. import java.util.ResourceBundle;
  3. /*
  4. 1 java.util.ResourceBundle : 它是一个抽象类
  5. 我们可以使用它的子类PropertyResourceBundle来读取以.properties结尾的配置文件
  6. 2 static ResourceBundle getBundle(String baseName) 可以根据名字直接获取默认语言环境下的属性资源。
  7. 参数注意: baseName
  8. 1.属性集名称不含扩展名。
  9. 2.属性集文件是在src目录中的
  10. 比如:src中存在一个文件 user.properties
  11. ResourceBundle bundle = ResourceBundle.getBundle("user");
  12. 3 ResourceBundle中常用方法:
  13. String getString(String key) : 通过键,获取对应的值
  14. 优点 : 快速读取属性文件的值
  15. 需求 :
  16. 通过ResourceBundle工具类
  17. 将一个属性文件 放到src目录中,使用ResourceBundle去获取键值对数据
  18. */
  19. public class ResourceBundleDemo {
  20. public static void main(String[] args) {
  21. // public static final ResourceBundle getBundle(String baseName)
  22. // baseName : properties文件的名字 , 注意 : 扩展名不需要加上 , properties必须在src的根目录下
  23. ResourceBundle resourceBundle = ResourceBundle.getBundle("user");
  24. // String getString(String key) : 通过键,获取对应的值
  25. String value1 = resourceBundle.getString("username");
  26. String value2 = resourceBundle.getString("password");
  27. System.out.println(value1);
  28. System.out.println(value2);
  29. }
  30. }

内容小结

  1. 如果要使用ResourceBundle加载属性文件,属性文件需要放置在哪个位置?

    1. src的根目录
  2. 请描述使用ResourceBundle获取属性值的大致步骤是怎样的?

    1. 1 获取ResourceBundle对象
    2. 2 通过ResourceBundle类中的getString(key) : 根据键找值