黑马程序员技术交流社区

标题: 【石家庄校区】就业班day09 --字节流 字符流 Properties [打印本页]

作者: xiekai_sjz    时间: 2018-9-25 21:07
标题: 【石家庄校区】就业班day09 --字节流 字符流 Properties
day09 字节流 字符流 Properties    今天我们来学习IO的相关知识。首先是读写文件的两种流-字节流、字符流。然后是与IO相关的集合Properties.
    以下是今天的学习目标:



以下是今天的详细笔记:
IO流IO的概念和分类IO流: 输入(Input)输出(Output)流
流: 数据流

输入: 从硬盘(文件)读取到内存(Java程序)
输出: 从内存(Java程序)写入到硬盘(文件)
        (入和出都是相对于内存来说的)
          +---------+
   输入    |         |   输出
--------> |   内存   | -------->
          |         |
          +---------+

IO流的分类:
    字节流 (读写字节: byte, 可以读写所有类型的文件, 包括视频, 图片, 音频, 文本等)
        字节输入流: java.io.InputStream 抽象类
        字节输出流: java.io.OutputStream 抽象类
    字符流 (读写字符: char, String, 只能读写文本文件)
        字符输入流: java.io.Reader 抽象类
        字符输出流: java.io.Writer 抽象类
输入流输出流
字节流 字节输入流 InputStream 字节输出流 OutputStream
字符流 字符输入流 Reader 字符输出流 Writer
字节流计算机中一切皆为字节
计算机中, 无论文本, 视频, 音频, 图片... 一切都是以"字节byte"形式存储的
也就是以数字形式存储的, 而数字可以用不同进制表示, 计算机能看懂的是二进制数字
字节输出流: OutputStream和FileOutputStream

java.io.OutputStream抽象类: 字节输出流 (顶层类)
        // 成员方法
        void close() :释放资源
        void flush() :刷新缓冲区(对于字节流来说没有作用)
        // 写字节的成员方法
        abstract void write(int b): 一次写一个字节 (参数int便于传递byte的整数不用强转)
        void write(byte[] b): 一次写一个字节数组
        void write(byte[] b, int offset, int len): 一次写一个字节数组的一部分
       
java.io.FileOutputStream类: 文件字节输出流 (向文件写数据)
        // 构造方法
        FileOutputStream(String name): 通过文件路径创建文件字节输出流
        FileOutputStream(File file): 通过File对象创建文件字节输出流
        构造方法的作用:
                1. 创建一个FileOutputStream对象
                2. 根据构造方法传递的路径, 在磁盘上创建一个空文件 ("如果文件存在则会清空数据")
                3. 将创建的FileOutputStream对象指向这个磁盘上的文件

字节输出流: 一次写一个字节到文件
写数据的原理:
        Java程序 -> JVM虚拟机 -> OS操作系统 -> OS调用写数据的方法 -> 将数据写入文件
       
使用字节输出流写数据到文件的步骤:
        1. 创建对象: 创建FileOutputStream对象, 构造方法中传递文件路径
        2. 写入数据: 使用FileOutputStream对象调用 write(int b) 方法, 将字节写入文件
        3. 释放资源: 使用FileOutputStream对象调用 close() 方法, 关闭流对象释放资源
       
        FileOutputStream fos = new FileOutputStream("模块名\\文件名.txt");
        fos.write(97);
        fos.close();
5分钟练习: 使用FileOutputStream写数据到文件
需求:
创建FileOutputStream对象, 路径传递当前模块下的testOutputStream1.txt文件  "day09\\testOutputStream1.txt"
写入97, 98, 99
释放资源
打开文件查看
代码:
[Java] 纯文本查看 复制代码
public class Test {
    public static void main(String[] args) throws IOException {  // 异常先声明抛出
        // 1. 创建流对象
        FileOutputStream fos = new FileOutputStream("day09\\testOutputStream1.txt");
        // 2. 写数据
        fos.write(97);
        fos.write(98);
        fos.write(99);
        // 3. 释放资源
        fos.close();
    }
}

文件存储原理和记事本打开文件的原理
向文件中写入字节数据时, 十进制的数字会被转换为"二进制"的数字写入文件

文本编辑器打开文本文件时, 会先查询编码表, 将二进制数字转换为对应的字符进行显示
        0-127: 查询ASCII码表  -128~127
        其他: 查询系统默认码表
                        Windows简体中文系统的程序打开是按 GBK 码表
                        IDEA中使用的是 UTF-8 码表   

ASCII编码表: 1个byte就是一个字符  97 a
GBK编码表:   2个byte数字组成一个汉字. "你": -60, -29
UTF-8编码表: 3个byte数字组成一个汉字. "你": -28, -67, -96
字节输出流: 一次写多个字节
java.io.FileOutputStream类: 文件字节输出流 (向文件写数据)
        void write(byte[] b): 一次写一个字节数组
        void write(byte[] b, int off, int len): 一次写一个字节数组的一部分
               
Java中, byte的范围是 -128 ~ 127 共256个数值
编码表中字符范围是       0 ~ 255 共256个数值
       
写多个字节时:
        如果第一个字节是正数中的 0~127, 则记事本会查询 ASCII码表 显示字符
        如果第一个字节是负数中的:-128~-1, 则记事本会查询 GBK码表 显示字符.(将两个连续的byte组合为一个中文)





补充:
[Java] 纯文本查看 复制代码
FileOutputStream fos = new FileOutputStream(new File("09_IOAndProperties\\b.txt"));
        
byte[] bytes2 = "你好".getBytes();
System.out.println(Arrays.toString(bytes2));//[-28, -67, -96, -27, -91, -67]
fos.write(bytes2);

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

字节输出流: 续写, 换行
java.io.FileOutputStream类: 文件字节输出流
        // 带有 续写 功能的构造方法, 不会清空文件
        FileOutputStream(String name, boolean append): 通过文件路径创建流, true可以续写
        FileOutputStream(File file, boolean append): 通过File对象创建流, true可以续写
       
换行符:
        Windows系统: "\r\n"
        Linux系统: "\n"
        MacOS系统: "\r"
5分钟练习: 续写和换行
需求:
创建FileOutputStream对象, 指向当前模块下的testOutputStream2.txt文件, 并开启续写
for循环5次, 每次循环写入"你好"的byte数组, 并写入windows的换行符的byte数组
循环结束后释放资源
运行程序查看效果, 再次运行再次查看效果
代码:
[Java] 纯文本查看 复制代码
public class Test {
    public static void main(String[] args) throws IOException {
        // 创建流对象
        FileOutputStream fos = new FileOutputStream("day09\\testOutputStream2.txt", true);

        // 循环写入
        for (int i = 0; i < 5; i++) {
            fos.write("你好".getBytes());
            fos.write("\r\n".getBytes());
        }

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

字节输入流: InputStream和FileInputStream

java.io.InputStream抽象类: 字节输入流 (顶层类)
        // 常用成员方法
        void close(): 释放资源
        // 读数据的方法
        int read(): 一次读一个字节
                读到文件末尾返回-1 (返回int也是为了代码编写方便)
        int read(byte[] b): 一次读一个字节数组
                读到的字节存放在参数中的字节数组中, 返回int值是本次读到的字节的个数. 读到文件末尾返回-1

java.io.FileInputStream类: 文件字节输入流
        // 构造方法
        FileInputStream(String name): 使用文件路径创建文件字节输入流
        FileInputStream(File file): 使用File对象创建文件字节输入流
        构造方法的作用:
                1. 创建FileInputStream对象
                2. 将FileInputStream对象指向磁盘上的文件
字节输入流: 一次读取一个字节
Java程序从文件读取数据的原理:
        Java程序 -> JVM虚拟机 -> OS(操作系统) -> OS调用读取的方法 -> 读取磁盘文件数据
       
java.io.InputStream抽象类: 字节输入流 (顶层类)
        int read(): 一次读一个字节
                读到文件末尾返回-1 (返回int也是为了代码编写方便)
       

FileInputStream读数据步骤:
        1. 创建FileInputStream对象
        2. 使用FileInputStream对象, 调用 int read() 方法, 一次读取一个byte
        3. 释放资源
[Java] 纯文本查看 复制代码
FileInputStream fis = new FileInputStream("模块名\\文件名");
        // 一次读一个字节:
        int by;   // int变量用来存储每次读到的数据
        while ((by = fis.read()) != -1) {
                System.out.print((char)by);  // 不要换行, 文件中自带换行的byte
        }

        fis.close();

5分钟练习: 一次读取一个字节
需求:
在当前模块中, 手动创建一个文件testInputStream1.txt, 双击打开直接在里面写入abc三个字母.
使用FileInputStream读取该文件, 一次读取一个byte, 每次将byte强转为char后, 打印到控制台
代码:
[Java] 纯文本查看 复制代码
public class Test {
    public static void main(String[] args) throws IOException {
        // 创建流对象
        FileInputStream fis = new FileInputStream("day09\\testInputStream1.txt");

        /*
            一次读一个字节
         */
        // 定义int类型变量, 用来接收每次读到的byte, 变量名随便起
        int by;
        // 循环读取
        while ((by = fis.read()) != -1) {
            // 读到一个byte, 会存在int变量中, 打印出来
//            System.out.print(by);
            System.out.print((char)by);
        }

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

字节输入流: 一次读取一个字节原理

字节输入流: 一次一个字节数组java.io.InputStream抽象类: 字节输入流 (顶层类)
        int read(byte[] b): 一次读一个字节数组
                参数 byte[] b 作用: 存储每次读到的字节, 起到缓冲作用
                返回值作用: 每次读到的字节个数, 读到文件末尾返回-1
[Java] 纯文本查看 复制代码
// 示例代码
FileInputStream fis = new FileInputStream("模块名\\文件名");

byte[] bytes = new byte[1024];  // 定义字节数组, 用于保存每次读取到的数据
int len;                        // 定义int变量, 用于保存每次读取到的长度
while ((len = fis.read(bytes)) != -1) {
    String s = new String(bytes, 0, len); // 将读取到的字节转换为字符串, 读到多少个就转换多少个
    System.out.print(s);
}

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


5分钟练习: 一次读取一个字节数组
需求:
在当前模块中, 手动创建一个文件testInputStream2.txt, 双击打开直接在里面写入ABCDE五个字母.
使用FileInputStream读取该文件, 使用一次读写一个字节数组的方式, 每次读到的数组转换为String, 打印到控制台
代码:
[Java] 纯文本查看 复制代码
public class Test {
    public static void main(String[] args) throws IOException {
        // 创建流对象
        FileInputStream fis = new FileInputStream("day09\\testInputStream2.txt");

        /*
            一次读一个字节数组
         */
        byte[] bytes = new byte[1024];  // 定义数组用来装每次读取到的字节数据
        int len;                        // 定义变量保存每次读取到的字节个数
        while ((len = fis.read(bytes)) != -1) {
            // 将读取到的字节数组转换为String
            String s = new String(bytes, 0, len);
            System.out.print(s);  // 打印不换行
        }

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

字节流复制图片文件
文件复制的步骤:
        1.创建一个字节输入流对象,构造方法中绑定要读取的数据源
        2.创建一个字节输出流对象,构造方法中绑定要写入的目的地
        3.使用字节输入流对象中的方法read读取文件
        4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中
        5.释放资源
[Java] 纯文本查看 复制代码
// 创建输入流和输出流
        FileInputStream fis = new FileInputStream("c:\\1.jpg");   //输入流指向要读的数据源文件
        FileOutputStream fos = new FileOutputStream("d:\\1.jpg"); //输出流指向要写的目的地文件
        // 一次读写一个字节数组
        byte[] bytes = new byte[1024];
        int len = 0;
        while((len = fis.read(bytes))!=-1){
                fos.write(bytes,0,len);
        }
        // 释放资源
        fos.close();
        fis.close();


5分钟练习: 字节流复制图片
需求:
将D盘中的"小岳岳.jpg"图片, 使用一次读写一个字节数组的方式, 复制到当前模块目录下, 名为"小岳岳复制.jpg"

分析:
        数据源:
        目的地:
代码:
[Java] 纯文本查看 复制代码
public class Test {
    public static void main(String[] args) throws IOException {
        // 创建流对象
        FileInputStream fis = new FileInputStream("d:\\小岳岳.jpg");
        FileOutputStream fos = new FileOutputStream("day09\\小岳岳复制.jpg");

        // 统计开始时间
        long start = System.currentTimeMillis();

        // 复制: 一次读写一个字节
        int by;
        while ((by = fis.read()) != -1) {
            // 将读到的字节写出
            fos.write(by);
        }

        // 复制: 一次读写一个字节数组
        /*byte[] bytes = new byte[1024];
        int len;
        while ((len = fis.read(bytes)) != -1) {
            // 读到多少个字节, 就写多少个字节, 不要全写
            fos.write(bytes, 0, len);
        }*/

        // 统计结束时间
        long end = System.currentTimeMillis();
        System.out.println("耗时:" + (end - start) + "毫秒");

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

字节流读取中文问题
GBK编码中, 一个汉字占用2个byte
UTF-8编码中, 一个汉字占用3个byte
字符流字符输入流: Reader和FileReader

注意: 字符流只能读写"文本文件"

java.io.Reader抽象类: 字符输入流 (顶层)
        // 常用成员方法
        void close() :关闭此流并释放与此流相关联的任何系统资源
        // 读
        int read(): 一次读一个字符char, 返回读到的字符.
            读到文件末尾返回-1  (返回int为了代码编写方便)
        int read(char[] cbuf): 一次读取一个字符数组char[]
                返回读取的字符个数. 读到文件末尾返回-1

java.io.FileReader类: 文件字符输入流
        // 构造方法
        FileReader(File file): 根据File对象创建文件字符输入流
        FileReader(String fileName): 根据File对象创建文件字符输入流
        构造方法的作用:
                1. 创建FileReader对象
                2. 将FileReader对象指向磁盘上的文件
字符输入流: 2种方式读取文本文件
java.io.Reader抽象类: 字符输入流 (顶层)
        int read(): 一次读一个字符char, 返回读到的字符.
            读到文件末尾返回-1  (返回int为了代码编写方便)
        int read(char[] cbuf): 一次读取一个字符数组char[]
                返回读取的字符个数. 读到文件末尾返回-1

java.lang.String类:
        String(char[] value): 将char数组转换为String
        String(char[] value, int offset, int count): 将char数组的一部分转换为String
[Java] 纯文本查看 复制代码
FileReader fr = new FileReader("a.txt");

// 一次读一个字符
int ch;  // 定义变量保存每次读到的字符
while ((ch = fr.read()) != -1) {
    System.out.print((char)ch);
}

// 一次读一个字符数组
char[] cs = new char[1024];
int len;
while ((len = fr.read(cs)) != -1) {
        String s = new String(cs, 0, len);
    System.out.print(s);
}

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

5分钟练习: 字符流读取文件
需求:
使用FileReader的 一次读写一个字符, 和 一次读写一个字符数组 2种方式, 读取当前模块下的随便某一个文本文件, 打印到控制台
代码:
[Java] 纯文本查看 复制代码
public class Test {
    public static void main(String[] args) throws IOException {
        // 创建流对象
        FileReader fr = new FileReader("day09\\src\\com\\itheima\\test01\\Test.java");

        // 读取: 一次读一个字符char
        /*int ch;  // 定义变量, 保存每次读到的字符
        while ((ch = fr.read()) != -1) {
            // 将读取到的字符打印
            System.out.print((char)ch);  // 不要换行, 因为读到的字符里面有换行符号
        }*/

        // 读取: 一次读一个字符数组char[]
        char[] chs = new char[1024];  // 定义字符数组, 保存每次读到的字符
        int len;                      // int变量用于保存每次读到的字符的个数
        while ((len = fr.read(chs)) != -1) {
            // 读到多少个, 就转换多少个, 不要全部转换
            String s = new String(chs, 0, len);
            System.out.print(s);   // 不要换行, 因为读到的字符里面有换行符号
        }

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

字符输出流: Writer和FileWriter

java.io.Writer抽象类: 字符输出流 (顶层类)   'a''b'  缓冲区    97 98
        // 常用成员方法
        abstract void close(): 刷新缓冲区并释放资源
        abstract void flush() :刷新缓冲区
        // 写
        void write(int c): 写一个字符 (int类型为了代码编写方便)
        void write(char[] cbuf): 写一个字符数组
        abstract void write(char[] b, int off, int len): 写一个字符数组的一部分
        void write(String str): 写一个字符串
        void write(String str, int off, int len): 写一个字符串的一部分
        注意: write()方法只是将数据写到内存缓冲区, 最后必须调用flush()或close()才能将数据真正写入磁盘

java.io.FileWriter类: 文件字符输出流
        // 构造方法
        FileWriter(File file): 通过File对象创建文件字符输出流
        FileWriter(String fileName): 通过文件路径创建文件字符输出流
        作用:
                1. 创建FileWriter对象
                2. 根据构造方法中的路径, 在磁盘上创建文件 ("如果文件已存在, 则清空文件内容")
                3. 将FileWriter对象指向磁盘上的文件
字符输出流: 一次写一个字符
void write(int c): 写一个字符 (int类型为了代码编写方便)

FileWriter使用步骤:
        1.创建FileWriter对象, 构造方法中绑定要写入数据的目的地
        2.使用FileWriter中的方法 write(), 把数据写入到"内存缓冲区"中(字符转换为字节的过程)
        3.使用FileWriter中的方法 flush(), 把内存缓冲区中的数据,"刷新到文件中"
        4.释放资源 close() (会先把内存缓冲区中的数据刷新到文件中)
[Java] 纯文本查看 复制代码
FileWriter fw = new FileWriter("09_IOAndProperties\\d.txt");
        fw.write(97);  // int ch 用int值代表char
        //fw.flush();
        fw.close();

字符输出流: flush与close区别
区别:
        flush(): 刷新缓冲区 (将数据从内存中写入到磁盘)
        close(): 刷新缓冲区, 并释放资源. 关闭流后不能再用同一个流对象操作

flush()可以省略, 只用close()来刷新并释放资源
字符输出流: 其他方法
写的其他方法:
        void write(char[] cbuf): 写一个字符数组
        abstract void write(char[] b, int off, int len): 写一个字符数组的一部分
        void write(String str): 写一个字符串
        void write(String str, int off, int len): 写一个字符串的一部分
5分钟练习: FileWriter其他方法
需求:
向当前模块中的testFileWriter.txt文件中, 分别使用以下方式写入数据:
        写一个字符方式, 写入 '0'
        写一个字符数组方式, 写入 {'a', 'b', 'c', 'd', 'e'}
        写一个字符数组的一部分方式, 写入上面数组的前3个字符
        写一个字符串的方式, 写入"传智播客"
        写一个字符串的一部分的方式, 写入"黑马程序员"的后3个字符串
代码:
[Java] 纯文本查看 复制代码
public class Test {
    public static void main(String[] args) throws IOException {
        // 创建流对象
        FileWriter fw = new FileWriter("day09\\testFileWriter.txt");

        // 写一个字符方式, 写入 '0'
        fw.write('0');
        // 写一个字符数组方式, 写入 {'a', 'b', 'c', 'd', 'e'}
        char[] chs = {'a', 'b', 'c', 'd', 'e'};
        fw.write(chs);
        // 写一个字符数组的一部分方式, 写入上面数组的前3个字符
        fw.write(chs, 0, 3);
        // 写一个字符串的方式, 写入"传智播客"
        fw.write("传智播客");
        // 写一个字符串的一部分的方式, 写入"黑马程序员"的后3个字符串
        fw.write("黑马程序员", 2, 3);

        // 刷新缓冲区并释放资源
        fw.close();
    }
}

字符输出流: 续写, 换行
FileWriter中带有续写功能的构造:
        FileWriter(File file, boolean append): 通过File对象创建流. 第二个参数为true可以续写
        FileWriter(String fileName, boolean append): 通过文件路径创建流. 第二个参数为true可以续写
       
换行:
        windows: "\r\n"  fw.write("\r\n");
补充:
字节流 和 字符流 如何选择:
        1. 如果不确定读写的是什么类型的数据, 用字节流最通用
        2. 如果确定读写的就是文本, 用字符流最方便
IO异常处理IO流操作中的异常处理
IO流的标准格式:
[Java] 纯文本查看 复制代码
FileWriter fw = null;
    try {
        //IO流对象的创建, 操作等代码
        fw = new FileWriter("d:\\09_IOAndProperties\\g.txt", true);
        for (int i = 0; i <10 ; i++) {
            fw.write("HelloWorld"+i+"\r\n");
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 释放资源
        if(fw != null){
            try {
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

JDK7和JDK9中IO异常处理的不同方式JDK 7 增加的 "try-with-resource"
        省略了 finally, 可自动释放资源
[Java] 纯文本查看 复制代码
// 格式
        try (创建流对象语句,如果多个,使用';'隔开) {
                // 读写数据   
        } catch (IOException e) {
                e.printStackTrace();   
        }
       
        // 示例
        try (FileWriter fw = new FileWriter("fw.txt");FileReader fr = new FileReader("fr.txt")) {
                // IO操作
                int ch = fr.read();
                fw.write(ch);
        } catch (IOException e) {
                e.printStackTrace();
        }

JDK 9 对于"try-with-resource"的改进:
        流对象的声明和创建可以放在括号外面
        流对象要求是有效final的.(即不要修改流对象的值)

[Java] 纯文本查看 复制代码
FileWriter fw = new FileWriter("fw.txt");
    FileReader fr = new FileReader("fr.txt");
    try (fw; fr) {
        // IO操作
        int ch = fr.read();
        fw.write(ch);
    } catch (IOException e) {
        e.printStackTrace();
    }

补充:
[Java] 纯文本查看 复制代码
public static void method(FileWriter fw, FileReader fr) {
    try (fw; fr) {
        // IO操作
        int ch = fr.read();
        fw.write(ch);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Properties集合Properties存储数据和遍历
Properties双列集合:
        键和值都是 String 类型

java.util.Properties类: 属性集, 属于Map的双列集合, 继承自Hashtable
        // 构造方法
        Properties(): 创建一个Properties集合
        // 可以使用Map接口中的方法
        // 特有成员方法
        Object setProperty(String key, String value): 保存/替换键值对
        String getProperty(String key): 通过键获取值. 键不存在返回null
        Set<String> stringPropertyNames(): 返回键的集合
        void store(OutputStream out, String comments): 将集合用字节流写入文件(不能中文),并写入注释
        void store(Writer writer, String comments): 将集合用字符流写入文件(可以中文),并写入注释
        void load(InputStream inStream): 从配置文件中通过字节流加载数据到Properties集合(不能读中文)
        void load(Reader reader): 从配置文件中通过字符流加载数据到Properties集合(可以读中文)
Properties: store()存储数据到文件
Properties将数据写入到文件的方法:
        void store(OutputStream out, String comments): 将集合用字节流写入文件(不能中文),并写入注释
        void store(Writer writer, String comments): 将集合用字符流写入文件(可以中文), 并写入注释
       
使用步骤:
        1.创建Properties集合对象,添加数据
        2.创建字节输出流/字符输出流对象,构造方法中绑定要输出的目的地
        3.使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储
        4.释放资源
补充:
属性集(配置文件), 标准的后缀是.properties
配置文件格式要求:
        一行一个键值对
        键和值中间用=分隔 (标准格式, 但空格分开也行)
        #表示单行注释

示例: db.properties
# This is a comment!
className=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
username=root
password=123456

5分钟练习: 使用Properties添加数据并写入文件
需求:
使用Properties集合, 添加以下键值对:
        "赵丽颖", "168"
        "迪丽热巴", "165"
        "古力娜扎", "160"
使用store(Writer writer, String comments)方法将数据写入到当前模块下的prop.properties文件中
代码:
[Java] 纯文本查看 复制代码
public class Test {
    public static void main(String[] args) throws IOException {
        // 创建Properties集合对象
        Properties properties = new Properties();

        // 添加键值对 setProperty(String key, String value)
        properties.setProperty("赵丽颖", "168");
        properties.setProperty("迪丽热巴", "165");
        properties.setProperty("古力娜扎", "160");

        // 创建文件字符输出流对象
//        FileWriter fw = new FileWriter("day09\\prop.properties");
        FileWriter fw = new FileWriter("day09\\prop.txt");

        // 将Properties集合中的数据, 写入到文件 store()
//        properties.store(fw, "");
        properties.store(fw, null);  // 第二个参数注释, 传递null也可以, 这样就不会出现空行注释

        // 关闭流
        fw.close();
    }
}

Properties: load()从文件加载数据到集合
Properties将数据从文件加载到集合中的方法:
        void load(InputStream inStream): 从配置文件中通过字节流加载数据到Properties集合(不能读中文)
        void load(Reader reader): 从配置文件中通过字符流加载数据到Properties集合(可以读中文)

使用步骤:
        1.创建Properties集合对象
        2.使用Properties集合对象中的方法load读取保存键值对的文件
        3.遍历Properties集合
5分钟练习: 加载文件数据到Properties
需求:
从刚才的prop.properties文件中, 使用load(Reader reader)方法加载数据到Properties集合, 使用Set<String> stringPropertyNames()方法遍历打印到控制台
代码:
[Java] 纯文本查看 复制代码
public class Test {
    public static void main(String[] args) throws IOException {
        // 创建Properties集合对象
        Properties properties = new Properties();

        // 创建文件字符输入流对象
        FileReader fr = new FileReader("day09\\prop.properties");

        // 从硬盘上读取到集合: load()
        properties.load(fr);  // 方法调用完毕后, 集合里面就有键值对了

        // 遍历集合
        Set<String> strings = properties.stringPropertyNames();
        for (String key : strings) {
            // 通过键获取值
            String value = properties.getProperty(key);
            System.out.println(key + "=" + value);
        }
    }
}

今日API
IO流:
java.io.OutputStream抽象类: 字节输出流 (顶层类)
        // 成员方法
        void close() :释放资源
        void flush() :刷新缓冲区(对于字节流来说没有作用)
        // 写字节的成员方法
        abstract void write(int b): 一次写一个字节 (参数是int是为了代码中写表示byte的整数方便不用强转)
        void write(byte[] b): 一次写一个字节数组
        void write(byte[] b, int off, int len): 一次写一个字节数组的一部分
       
java.io.FileOutputStream类: 文件字节输出流 (向文件写数据)
        // 构造方法
        FileOutputStream(String name): 通过文件路径创建文件字节输出流
        FileOutputStream(File file): 通过File对象创建文件字节输出流
        FileOutputStream(String name, boolean append): 通过文件路径创建文件字节输出流, true可以续写
        FileOutputStream(File file, boolean append): 通过File对象创建文件字节输出流, true可以续写
       
java.io.InputStream抽象类: 字节输入流 (顶层类)
        // 常用成员方法
        void close(): 释放资源
        // 读数据的方法
        int read(): 一次读一个字节. 读到文件末尾返回-1 (返回int也是为了代码编写方便)
        int read(byte[] b): 一次读一个字节数组. 读到的字节存放在参数中的字节数组中, 返回int值是本次读到的字节的个数. 读到文件末尾返回-1

java.io.FileInputStream类: 文件字节输入流
        // 构造方法
        FileInputStream(String name): 使用文件路径创建文件字节输入流
        FileInputStream(File file): 使用File对象创建文件字节输入流
       
java.io.Reader抽象类: 字符输入流 (顶层)
        // 常用成员方法
        void close() :关闭此流并释放与此流相关联的任何系统资源
        // 读数据的方法
        int read(): 一次读一个字符char, 返回读到的字符. 读到文件末尾返回-1  (返回int为了代码编写方便)
        int read(char[] cbuf): 一次读取一个字符数组char[]. 返回读取的字符个数. 读到文件末尾返回-1

java.io.FileReader类: 文件字符输入流
        // 构造方法
        FileReader(File file): 根据File对象创建文件字符输入流
        FileReader(String fileName): 根据File对象创建文件字符输入流
       
java.io.Writer抽象类: 字符输出流 (顶层类)
        // 常用成员方法
        abstract void close(): 刷新缓冲区并释放资源
        abstract void flush() :刷新缓冲区
        // 写
        void write(int c): 写一个字符 (int类型为了代码编写方便)
        void write(char[] cbuf): 写一个字符数组
        abstract void write(char[] b, int off, int len): 写一个字符数组的一部分
        void write(String str): 写一个字符串
        void write(String str, int off, int len): 写一个字符串的一部分
       
java.io.FileWriter类: 文件字符输出流
        // 构造方法
        FileWriter(File file): 通过File对象创建文件字符输出流
        FileWriter(String fileName): 通过文件路径创建文件字符输出流
        FileWriter(File file, boolean append): 通过File对象创建文件字符输出流. 第二个参数为true可以续写
        FileWriter(String fileName, boolean append): 通过文件路径创建文件字符输出流. 第二个参数为true可以续写
       
集合:
java.util.Properties类: 属性集, 属于Map的双列集合, 继承自Hashtable
        // 构造方法
        Properties(): 创建一个Properties集合
        // 可以使用Map接口中的方法
        // 特有成员方法
        Object setProperty(String key, String value): 保存/替换键值对
        String getProperty(String key): 通过键获取值. 键不存在返回null
        Set<String> stringPropertyNames(): 返回键的集合
        void store(OutputStream out, String comments): 将集合数据用字节流写入文件(不能中文), 并写入注释
        void store(Writer writer, String comments): 将集合数据用字符流写入文件(可以中文), 并写入注释
        void load(InputStream inStream): 从配置文件中通过字节流加载数据到Properties集合(不能读中文)
        void load(Reader reader): 从配置文件中通过字符流加载数据到Properties集合(可以读中文)
IO流
截止今日的IO流体系结构字节流        |_ InputStream                            字节输入流顶层                |_ FileInputStream              文件字节输入流        |_ OutputStream                        字节输出流顶层                |_ FileOutputStream          文件字节输出流字符流        |_ Reader                                     字符输入流顶层                |_ FileReader                      文件字符输入流        |_ Writer                                      字符输出流顶层                |_ FileWriter                       文件字符输出流



































作者: cuipu    时间: 2018-9-26 08:12
又是沙发
作者: cuipu    时间: 2018-9-26 08:12
第八天的貌似没有




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2