IO流---黑马Java基础学习笔记

黑马java基础IO流学习网址

IO流

一、什么是io流

I:input 输入(读取)

O:output 输出(写入)

流:数据(字符、字节)1个字符 = 2个字节,一个字节 = 8个二进制位

简单的说就是:读取与写入

输入:把数据从硬盘上,读取到内存中使用

输出:把内存中的数据,写出到硬盘上保存

输入流 输出流
字节流 字节输入流 InputStream 字节输出流 OutputStream
字符流 字符输入流 Reader 字符输出流 Writer

Java 中 I/O 操作主要是指使用 java.io 包下的内容,进行输入、输出操作。输入也叫做读取数据,输出也叫做写出数据。

二、字节流

2.1字节输出流【OutputStream】

java.io.OutputStream 抽象类是表示字节输出流的所有类的超类,将制定的字节信息写出到目的地,它定义了字节输出流的基本共性功能方法。

void close() 关闭此输出流并释放与此流相关联的任何系统资源。
void flush() 刷新此输出流并强制任何缓冲的输出字节被写出。
void write(byte[] b)b.length字节从指定的字节数组写入此输出流。
void write(byte[] b, int off, int len) 从指定的字节数组写入 len个字节,从偏移 off开始输出到此输出流。
abstract void write(int b) 将指定的字节写入此输出流。

close方法,当完成流的操作时,必须调用此方法,释放系统资源

FilterOutputStream类

java.io.FilterOutputStream 类是文件字节输出流,用于将内存中的数据写入到硬盘的文件中。

扫描二维码关注公众号,回复: 12549883 查看本文章
构造方法

FileOutputStream(File file) 创建文件输出流以写入由指定的 File 对象表示的文件。

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

参数:写入数据的目的地

File file:目的地是一个文件

String name:目的地是一个文件的路径

作用

  1. 创建一个 fileOutputStream 对象
  2. 会根据构造方法中传递的文件、文件路径,创建一个空的文件。
  3. 会把 FileOutputStream 对象指向创建好的文件
原理

java程序–>JVM(java虚拟机)–>os(操作系统)–>os调用写数据的方法–>把数据写入到文件中

步骤(重点)
  1. 创建一个 FileOutputStream 对象,构造方法中传递写入数据的目的地
  2. 调用 FileOutputStream 对象中的方法 write,把数据写入到文件中
  3. 释放资源(流使用会占用一定的内存,使用完毕要把内存清空,提供程序的效率)
import java.io.FileOutputStream;
import java.io.IOException;

public class MyOutputStream {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //报错,需要抛出一个文件找不到异常“throws IOException”
        //1. 创建一个FileOutputStream 对象,构造方法中传递写入数据的目的地
        FileOutputStream fos = new FileOutputStream("I:\\javaclass\\src\\com\\sxmz\\IoClass\\class01\\a.txt");
        //2.调用 FileOutputStream 对象中的方法 write(文件指定输出流),把数据写入到文件中
        fos.write(97);
        //3.释放资源(流使用会占用一定的内存,使用完毕要把内存清空,提供程序的效率)
        fos.close();
    }

}
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

public class MyOutputStream02 {
    
    
    public static void main(String[] args) throws IOException {
    
    
        FileOutputStream fos = new FileOutputStream("I:\\javaclass\\src\\com\\sxmz\\IoClass\\class01\\b.txt");
        //一次只能写一个,很麻烦
        fos.write(49);
        fos.write(48);
        fos.write(48);
        /*
        byte[] b 将b.length 字节从指定的字节数组写入此输出流。
        一次写多个字符:
        如果写的第一个字节是正数(0-127),那么显示的时候会查询ASCII表
        如果写的是一个字节是负数,
        那么第一个字节会和第二个字节,
        两个字节组成一个中文显示
        查询系统默认码表(GBK)
         */
        byte[]bytes = {
    
    65,66,67,68,69};//ABCDE
        //byte[]bytes2 = {-65,-66,-67,68,69,-70,71};//烤紻E篏
        fos.write(bytes);
        //fos.write(bytes2);
        /*
        write(byte[] b,  int off, int len)
        从指定的字节数组写入 len个字节,
        从偏移 off开始输出到此输出流。
         */
        fos.write(bytes,1,3);
        /*
        写入字符的方法:可以使用String类中的方法把字符串转换为字节数组
        byte[] getBytes 把字符串转换为字节数组
         */
        byte[] bytes3 = "你好".getBytes();
        //[-28, -67, -96, -27, -91, -67]
        System.out.println(Arrays.toString(bytes3));
        fos.write(bytes3);
        fos.close();
    }
}

write():单个输入

write(byte[] b) :字节数组输入

write(byte[] b, int off, int len):指定某一数组位置

byte[] getBytes:利用getBytes可将String类字符串转换为字节数组

文件存储原理和即使本打开文件的原理

写数据的时候,会把10进制的整数97,转换为二进制整数97,。

fos.write(1100001);97–>1100001

任意的文本编译器(记事本,notepad++…)

在打开文件的时候,都会查询编码表,把字节转换为字符表示

0-127:查询ASCII表示(97–>a)

其他值:查询系统默认码表(中文系统GBK)

数据追加续写

FileOutputStream(String name, boolean append) 创建文件输出流以指定的名称写入文件。

FileOutputStream(File file, boolean append) 创建文件输出流以写入由指定的 File对象表示的文件

String name,File file:写入数据的目的地

boolean append:追加写开关

  • true:创建对象不会覆盖原源文件,继续在文件的末尾追加写数据

  • false:创建一个新文件,覆盖源文件

数据换行

写换行代码

windows:\r\n

Linux:/n

mac:/r

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

public class MyOutputStream03 {
    
    
    public static void main(String[] args) throws IOException {
    
    
        FileOutputStream fos = new FileOutputStream("src\com\sxmz\IoClass\class01\c.txt",true);
        for (int i = 0; i <=10 ; i++) {
    
    
            fos.write("你好".getBytes());
            fos.write("\r\n".getBytes());
        }
        fos.close();
    }
}

2.2字节输入流【InputStream】

java.io.InputStream此抽象类是表示字节输入流的所有类的超类

read() 从输入流读取数据的下一个字节

read(byte[] b) 从输入流读取一些字节数,并将它们存储到缓冲区 b

close() 关闭此输入流并释放与流相关联的任何系统资源

FileInputStream类【文件字节输入流】

FileInputStream文件字节输入流

java.io.FileInputStream extemds InputStream

作用:把硬盘文件中的数据,读取到内存中使用

构造器方法

FileInputStream(String name)

FileInputStream(File file)

参数:读取文件的数据流

​ String name:文件的路径

​ File file:文件

作用

  1. 会创建一个 FileInputStream 对象
  2. 会把 FileInputStream 对象指定构造方法中要读取的文件
原理

硬盘–>内存

java程序–>JVM–>os–>os读取数据的方法–>读取文件

步骤(重点)
  1. 创建 FileInputStream 对象,构造方法中绑定要读取的数据源
  2. 使用 FileInputStream 对象中的方法read ,读取文件
  3. 释放资源
import java.io.FileInputStream;
import java.io.IOException;
public class MyInputStream {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //创建 FileInputStream 对象,构造方法中绑定要读取的数据源
        FileInputStream fis = new FileInputStream("src\\com\\sxmz\\IoClass\\class01\\a.txt");
        //使用 FileInputStream 对象中的方法read ,读取文件
        //int redd()读取文件中的字节并返回,同时位置递增,读取到文件的末尾返回-1
       /* int len = fis.read();
        System.out.println(len);    //a-97
         len = fis.read();          //上次赋值后,位置已递增至后一位
        System.out.println(len);    //b-98
         len = fis.read();
        System.out.println(len);    //c-99
         len = fis.read();
        System.out.println(len);    //-1
        */
        /*
          发现以上读取文件是重复的过程,所以可以使用循环优化
          不知道文件中有多少字节,使用while循环
          while 循环结束条件,读取到-1的时候结束

          布尔表达式(len=fis.read()) !=-1
            1.fis.read():读取一个字节
            2.len = fis.read():把读取的字节赋值给变量len
            3.len=fis.read()) !=-1:判断变量len是否不等于-1
         */
        int len = 0;
        while ((len=fis.read()) !=-1){
    
    
            System.out.print(len+" ");
            System.out.println((char)len+" ");
        }
        /*
        while (fis.read() !=-1){
            System.out.println(fis.read()); //输出结果为:98 , -1
            //由于fis.read()判断成功后递进为98位,打印结果就为98.同时又递进为99位
            //99位再次判断成功后递进为-1位,再次打印就为-1
            //所有需要将fis.read()赋值给变量len进行打印
        }
         */
        //释放资源
        fis.close();

    }
}

读取多个字节

int read(byte[] b) 从输入流中读取一定数量的字节,并将它们存储到缓冲区 b 中。

明确两件事情

  1. 方法的参数 byte[] 的作用?

    起到缓存作用,存储每次读取到的多个字节

    数组的长度一般定义为1024(1kb) 或者 1024的倍数

  2. 方法的返回值 int 是什么?

    每次读取的有效字节个数

    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.util.Arrays;
    
        //String类的构造方法
            //String(byte[] bytes):把字节数组转换为字符串
            //String(byte[] bytes, int offset, int length) :把字节数组的一部分转换为字符串
            //offset:数组的开始索引;   length:转换的字节个数
    
    public class MyInputStream02 {
          
          
        public static void main(String[] args) throws IOException {
          
          
            //创建FileInputStream对象, 构造方法中绑定要读取的数据源
            FileInputStream fis = new FileInputStream("sxmz\\src\\com\\sxmz\\IoClass\\class01\\b.txt");
            //使用FileInputStream对象中的方法read读取文件
            //int read(byte[] b)从输入流中读取一定数量的文字,并将其存储在缓冲区 b 中。
    
            /*byte[] bytes = new byte[2];
            int len = fis.read(bytes);
            System.out.print(len+" ");//2
            System.out.print(Arrays.toString(bytes)+" "); //65,66
            System.out.println(new String(bytes));  //AB
    
            len = fis.read(bytes);
            System.out.print(len+" ");//2
            System.out.print(Arrays.toString(bytes)+" "); //65,66
            System.out.println(new String(bytes));  //CD
    
            len = fis.read(bytes);
            System.out.print(len+" ");//1
            System.out.print(Arrays.toString(bytes)+" "); //65,66
            System.out.println(new String(bytes));  //ED
            // 由于有效字节个数为1,将0位置覆盖,而1位置没有覆盖所以还是之前数组
    
            len = fis.read(bytes);
            System.out.print(len+" ");//-1
            System.out.print(Arrays.toString(bytes)+" "); //65,66
            System.out.println(new String(bytes));  //ED
            // 没有有效字节显示-1(结束标记为jVM设定值),由于没有覆盖,所以打印之前数组*/
    
            //循环简化
            byte[] bytes = new byte[1024];
            int len = 0;
            while (( len = fis.read(bytes))!=-1){
          
          
                //String(byte[] bytes, int offset, int length) :把字节数组的一部分转换为字符串
                System.out.println(new String(bytes,0,len));
            }
    
            fis.close();
        }
    }
    
    

2.3练习:图片复制

文件复制:一读一写

一切的文本都是由字节组成

明确
数据源:c:\
数据的目的地:D:\

文件复制的步骤

  1. 创建一个字节输入流对象,构造方法中绑定要读取的数据源
  2. 创建一个字节输出流对象,构造方法中绑定要写入的目的地
  3. 使用字节输入流中的方法read读取文件
  4. 使用字节输出流中的write,把读取到的字节写入到目的地文件中
  5. 释放资源
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class MyCopyFile {
    
    
    public static void main(String[] args) throws IOException {
    
    
        long s = System.currentTimeMillis();//当前时间
        //1.
        FileInputStream fis = new FileInputStream("c:\\1.jpg");
        //2.
        FileOutputStream fos = new FileOutputStream("d:\\1.jpg");
        //3.
        /*int len = 0;
        while ((len = fis.read())!=-1){
        //4.
            fos.write(len);
        }
        速度太慢,每次字节都要读取、打印
        */
        byte[] bytes = new byte[1024];
        int len = 0;
        while ((len = fis.read(bytes)) != -1){
    
    
            fos.write(bytes,0,len);
        }
        fos.close();
        fis.close();
        long e = System.currentTimeMillis();//当前时间
        //总用时时间
        System.out.println("复制文件共耗时:"+(e-s)+"毫秒")
    }
}

注意

释放资源,先关写,后关读。因为写完肯定读完,但读完不一定写完

三、字符流

中文字符时,可能会显示不完整的字符。因为一个中文同时使用多个字节(GBK使用2个字节,UTF-8使用3个字节),而一次只能输出一个字节。

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

public class MyStream {
    
    
    public static void main(String[] args) throws IOException {
    
    
        FileInputStream fis = new FileInputStream("D:\\javaclass\\sxmz\\src\\com\\sxmz\\IoClass\\class01\\c.txt");
        int len = 0;
        while ((len = fis.read())!=-1){
    
    
            System.out.println(len);    //输出6个字节
            System.out.println((char)len);  //编程char类型就会乱码,因为一次读取了3/1个中文
        }
        fis.close();
    }
}

3.1字符输入流【Reader】

java.io.Reader所有字符输入流的超类

read()读一个字符

read(char[] cbuf)将字符读入数组

【FileReader】文件字符输入流

java.io.FileReader extends InputStreamReader(转换流) extends Reader

作用:把硬盘文件中的数据以字符的方式读取到内存中

构造方法

FileReader(String fileName)

FileReader(File file)

参数:读取文件的数据源

String fileName:文件的路径

File file:一个文件

作用

  1. 创建一个FileReader对象
  2. 会把FileReader对象指向要读取的文件
使用步骤
  1. 创建FileReader对象,构造方法中绑定要读取的数据源
  2. 使用FileReader对象中的方法read读取文件
  3. 释放资源
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class MyReader02 {
    
    
    public static void main(String[] args) throws IOException {
    
    
        FileReader fr = new FileReader("sxmz\\src\\com\\sxmz\\IoClass\\class01\\c.txt");
        /*//int read() 读取单字符并返回
        int len = 0;
        while ((len = fr.read())!=-1){
            System.out.print(len+":");
            System.out.print((char) len+"; ");
        }*/

        //int read(char[] cbuf) 一次读取多个字符,将字符读入数组中。
        char[] cs = new char[1024];
        int len = 0;    //记录的每次读取的有效字符个数
        while ((len = fr.read(cs))!= -1){
    
    
            /*
            String类的构造方法
            String(char[] value) 把字符数组转换为字符串
            String(char[] value, int offset, int count) 把字符数组的一部分转换为字符串;
            offset 数组的开始索引 count 转换个个数
             */
            System.out.println(new String(cs,0,len));
        }
        fr.close();
    }
}

3.2字节输出流【Writer】

java.io.Writer: 字符输出流,所有字符输出流的最顶层父类,是个抽象类。

void write(int c)写一个字符

void write(char[] cbuf)写入一个字符数组。

abstract void write(char[] cbuf, int off, int len)写入字符数组的一部分。

void write(String str)写一个字符串

void write(String str, int off, int len)写一个字符串的一部分。

abstract void flush()刷新流。

abstract void close()关闭流,先刷新。

【FileWriter】文件字符输出流

java.io.FileWriter extends OutputStreamWriter extends Writer

FileWriter:文件字符输出流

作用:把内存中字符数据写入到文件中

构造方法

FileWriter(File file) 给一个File对象构造一个FileWriter对象。

FileWriter(String fileName) 构造一个给定文件名的FileWriter对象。

参数:写入参数的目的地

String fileName:文件的路径

File file:一个文件

作用

  1. 会创建一个FileWriter对象
  2. 会根据构造方法中传递的文件/文件的路径,创建文件
  3. 会把FileWriter对象指向创建好的文件
使用步骤
  1. 创建FileWriter对象,构造方法中绑定要写入数据的目的地
  2. 使用FileWriter中的方法write,把数据写入到内存缓冲区中(字符转换为字节的过程)
  3. 使用FileWriter中方法flush,把内存缓冲区中的数据,刷新到文件中
  4. 释放资源(会先把内存缓存区内的数据刷新到文件中)
import java.io.FileWriter;
import java.io.IOException;

public class MyWriter {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //创建`FileWriter`对象,构造方法中绑定要写入数据的目的地
        FileWriter fw = new FileWriter("sxmz\\src\\com\\sxmz\\IoClass\\class01\\d.txt");
        //使用`FileWriter`中的方法`write`,把数据写入到**内存缓冲区**中(字符转换为字节的过程)
        //void write(int c)
        fw.write(97);
        /*//使用`FileWriter`中方法`flush`,把内存缓冲区中的数据,刷新到文件中
        fw.flush();*/
        //释放资源(会先把内存缓存区内的数据刷新到文件中)
        fw.close();
        /*如果没有使用 flush 或 close 刷新,当程序结束时,
        存在内存缓冲区内的字符就会自动清除,无法保存在指定文件中*/
    }
}

关闭和刷新的却别

flush :刷新缓冲区,流对象可以继续使用

close:先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用。

import java.io.FileWriter;
import java.io.IOException;

public class MyCloseAndFlush {
    
    
    public static void main(String[] args) throws IOException {
    
    

        FileWriter fw = new FileWriter("sxmz\\src\\com\\sxmz\\IoClass\\class01\\e.txt");

        fw.write(97);
        fw.flush();

        fw.write(98);
        //flush刷新后还可以使用write,但需要再次flush刷新或close
        fw.flush();
        
        fw.write(99);
        fw.close();
        //fw.write(99); 报错:IOException: Stream closed
        //close 方法之后流已经关闭,已经从内测中消失,流不能再被使用。

}
}

其他方法

void write(char[] cbuf)写入一个字符数组。

abstract void write(char[] cbuf, int off, int len)写入字符数组的一部分。

void write(String str)写一个字符串

void write(String str, int off, int len)写一个字符串的一部分。

import java.io.FileWriter;
import java.io.IOException;

public class MyWriter02 {
    
    
    public static void main(String[] args) throws IOException {
    
    
        FileWriter fw = new FileWriter("sxmz\\src\\com\\sxmz\\IoClass\\class01\\f.txt");
        //`void write(char[] cbuf)`写入一个字符数组。
        char[] cs = {
    
    'a','b','c','d','e'};
        fw.write(cs);

        //`abstract void write(char[] cbuf, int off, int len)`写入字符数组的一部分。
        fw.write(cs,1,3);
        
        //`void write(String str)`写一个字符串
        fw.write("传智播客");

        //`void write(String str, int off, int len)`写一个字符串的一部分。
        fw.write("黑马程序员",2,3);
        
        fw.close();
    }
}

续写和换行

FileWriter(String fileName, boolean append) 构造一个FileWriter对象,给出一个带有布尔值的文件名,表示是否附加写入的数据。

FileWriter(File file, boolean append) 给一个File对象构造一个FileWriter对象。

参数

String fileName,File file:写入数据的目的地

boolean append:续写开关,true:不会创建新的文件覆盖源文件,可以续写;false:创建新的文件覆盖源文件

换行:换行符号

windows:\r\n

Linux:/n

mac:/r

import java.io.FileWriter;
import java.io.IOException;

public class MyWriter03 {
    
    
    public static void main(String[] args) throws IOException {
    
    
        FileWriter fw = new FileWriter("sxmz\\src\\com\\sxmz\\IoClass\\class01\\g.txt",true);
        for (int i = 0; i <10 ; i++) {
    
    
            fw.write("HelloWorld,"+i+"\r\n");
        }
        fw.close();
    }
}

四、IO异常的处理

JDK7之前[try…catch…finally]

之前的入门练习,我们一直把异常抛出,而实际开发中并不能这样处理。

在 jdk1.7 之前使用try...catch...finally代码块,处理流中异常。

格式

try{
    
    
    可能会产生异常的代码
}catch(异常类变量 变量名){
    
    
    异常的处理逻辑
}finally{
    
    
    一定会指定的代码
    资源释放
}

练习

import java.io.FileWriter;
import java.io.IOException;

public class MyTryCatch {
    
    
    public static void main(String[] args) {
    
    
        //将fw的作用域提高,让finally可以使用
        //变量在定义的时候,可以没有值,但是使用的时候必须有值
        //如果不赋值,当try执行失败,fw没有值,fw.close会报错
        FileWriter fw = null;
        try{
    
    
            //可能会产生异常的代码
            fw = new FileWriter("w:sxmz\\src\\com\\sxmz\\IoClass\\class01\\g.txt",true);
            for (int i = 0; i <10 ; i++) {
    
    
                fw.write("HelloWorld,"+i+"\r\n");
            }
        }catch (IOException e){
    
    
            //异常的处理逻辑
            System.out.println(e);
        }finally {
    
    
            //一定会执行的代码
            if (fw!=null){
    
    
                try {
    
    
                fw.close();     //close方法本身是会有抛出异常对象,所有需要再次进行try...catch要么throws
             } catch (IOException e) {
    
    
                e.printStackTrace();
             }
            }
            /*当路径不正取时,除了已设定的正常抛出,还出现NullPointerException(空指针异常);
            是由于创建对象失败,fw默认值为null,而null是不能够调用方法的,所以会抛出NullPointerException(空指针异常);
            所以需要增加一个判断if,当fw不是null时再把资源释放
             */
        }
    }
}

JDK7的新特性

try的后边可以增加一个(),在括号中可以定义流对象,这个流对象的作用域就在try中有效

try中的代码执行完毕,会自动把流对象释放,不用写finally

格式

try(定义流对象;定义流对象...){
    
    
    可能会产生异常的代码
}catch(异常类变量 变量名){
    
    
    异常的处理逻辑
}
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class MyJDK7 {
    
    
    public static void main(String[] args) {
    
    
        try(    //定义流对象
                FileInputStream fis = new FileInputStream("c:\\1.jpg");
                FileOutputStream fos = new FileOutputStream("d:\\1.jpg");
                ) {
    
         //可能会产生异常的代码
            int len = 0;
            while ((len = fis.read())!=-1){
    
    
                fos.write(len);
            }

        }catch (IOException e){
    
    
            //异常的处理逻辑
            System.out.println(e);
        }
        //由于流对象只存在于`try`中,所以当代码执行完毕时就对自动释放
    }
}

JDK9的新特性

try的前边可以定义流对象,在try后边()中可以直接引入流对象的名称(变量名),在try代码执行完毕后,流对象也可以释放掉,不用写finally

格式

A a = new A();
B b = new B();
try(a,b){
    
    
    可能会产生异常的代码
}catch(异常类变量 变量名){
    
    
    异常的处理逻辑
}

练习

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

public class MyJDK9 {
    
    
    public static void main(String[] args) throws FileNotFoundException {
    
    
        FileInputStream fis = new FileInputStream("c:\\2.jpg");
        FileOutputStream fos = new FileOutputStream("d:\\2.jpg");
        try(fis;fos) {
    
    	//**报错**
            int len = 0;
            while ((len = fis.read())!=-1){
    
    
                fos.write(len);
            }
        }catch (IOException e){
    
    
            System.out.println(e);
        }
    }
}

JDK9比较麻烦,即要try...catch又要throws

try(fis;fos)不清楚什么情况报错,提示需要<标识符>;视频中并没有报错

五、属性集

【Propertise】集合

  • java.lang.Object
    • java.util.Dictionary<K,V>
      • java.util.Hashtable<Object,Object>
        • java.util.Properties

java.util.Properties集合 extends Hashtable<k,v> implements Map<k,v>

Propertise 类表示了一个持久的属性集合。Propertise 可保存在流中或从流中加载。

Propertise集合是一个唯一和IO流相结合的集合

  • 可以使用Propertise集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储
  • 可以使用Propertise集合中的方法load,把硬盘中保存的文件(键值对),读取到集合中使用

属性列表中每个键及其对应值都是一个字符串

Propertise集合是一个双列集合,keyvalue默认都是字符串

Propertise集合有一些操作字符串的特有方法
Object setProperty(String key, String value)调用Hashtable的方法put
String getProperty(String key)通过key找到value值,此方法相当于Map集合中的get(key)方法
Set< String > stringPropertyNames() 返回此属性列表中的一组键,其中键及其对应的值为字符串,
此方法相当于Map集合中的keySet方法

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

public class MyPropertise {
    
    
    public static void main(String[] args) {
    
    
        show01();
    }
    /*
        使用Propertise集合存储数据,遍历取出Propertise集合中的数据
        Propertise集合是一个双列集合,key和value默认都是字符串
        Propertise集合有一些操作字符串的特有方法
            Object setProperty(String key, String value) 调用 Hashtable的方法 put 。
            String getProperty(String key) 通过key找到value值,此方法相当于Map集合中的get(key)方法
            Set<String> stringPropertyNames() 返回此属性列表中的一组键,其中键及其对应的值为字符串,
            此方法相当于Map集合中的keySet方法
     */

    private static void show01() {
    
    
         //创建一个Propertise集合对象
        Properties prop = new Properties();
        //使用setProperty往集合中添加数据
        prop.setProperty("颖","168");
        prop.setProperty("巴","165");
        prop.setProperty("扎","160");
        //prop.put(1,true); 可以使用任何类型

        //使用stringPropertyNames()把Property集合中的键取出,存储到一个Set集合中
        Set<String> set = prop.stringPropertyNames();
        for (String key : set){
    
    
            String value = prop.getProperty(key);
            System.out.println(key+"="+value);
        }
        String key = "颖";
        String value = prop.getProperty(key);
        System.out.println(key+"="+value);
    }
}

store方法

可以使用Propertise集合中的方法store,把集合中的临时数据,持久化写入到硬盘存储
void store(OutputStream out, String comments)
void store(Writer writer, String comments)
参数
OutputStream out:字节输出流,不能写入中文
Writer writer:字符输出流,可以写入中文
String comments:注释,用来解释说明保存的文件是做什么用的
不能使用中文,会产生乱码,由于默认是Unicode编码,而电脑系统常使用UTF-8
一般使用“ ”空字符串

使用步骤

  1. 创建Propertis集合对象,添加数据
  2. 创建字节输出流/字符输出流对象,构造方法中绑定要输出的目的地
  3. 使用Propertis集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储
  4. 释放资源
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;

public class MyPropertise {
    
    
    public static void main(String[] args) throws IOException {
    
    
        show02();
    }
    /*
    可以使用Propertise集合中的方法store,把集合中的临时数据,持久化写入到硬盘存储
    void store(OutputStream out, String comments)
    void store(Writer writer, String comments)
    参数:
        OutputStream out:字节输出流,不能写入中文
        Writer writer:字符输出流,可以写入中文
        String comments:注释,用来解释说明保存的文件是做什么用的
                不能使用中文,会产生乱码,由于默认是Unicode编码,而电脑系统常使用UTF-8
                一般使用“ ”空字符串

     */

    private static void show02() throws IOException {
    
    
        //创建Propertis集合对象,添加数据
        Properties prop = new Properties();
        prop.setProperty("颖","168");
        prop.setProperty("巴","165");
        prop.setProperty("扎","160");
        /*//创建字节输出流/字符输出流对象,构造方法中绑定要输出的目的地
        FileWriter fw = new FileWriter("sxmz\\src\\com\\sxmz\\IoClass\\class01\\prop.txt");
        //使用Propertis集合中的方法`store`,把集合中的临时数据,持久化写入到硬盘中存储
        prop.store(fw," ");
        //释放资源
        fw.close();*/
        prop.store(new FileOutputStream("sxmz\\src\\com\\sxmz\\IoClass\\class01\\prop2.txt")," ");
        //如果使用字节流中文会出现乱码
        //同时由于此IO是匿名对象,当使用完会自动释放,所以不需要close。
    }

load方法

可以使用Propertise集合中的方法load,把硬盘中保存的文件(键值对),读取到集合中使用
void load(InputStream inStream)
void load(Reader reader)

参数

InputStream inStream:字节输入流,不能读取含有中文的键值对

Reader reader:字符输入流,能读取含有中文的键值对

使用步骤

  1. 创建Propertise集合对象
  2. 使用Propertise集合对象中的方法load读取保存键值对的文件
  3. 遍历Propertise集合

注意

  • 存储键值对的文件中,键与值默认的连接符号可以使用=,空格(其他符号)
  • 存储键值对的文件中,可以使用#进行注释,被注释的键值对不会再被读取
  • 存储键值对的文件中,键与值默认都是字符串,不用再加引号
import java.io.*;
import java.util.Properties;
import java.util.Set;

public class MyPropertise {
    
    
    public static void main(String[] args) throws IOException {
    
    
        show03();
    }
    /*
        可以使用Propertise集合中的方法load,把硬盘中保存的文件(键值对),读取到集合中使用
        void load(InputStream inStream)
        void load(Reader reader)
     */

    private static void show03() throws IOException {
    
    
        Properties prop = new Properties();
        prop.load(new FileReader("sxmz\\src\\com\\sxmz\\IoClass\\class01\\prop.txt"));
        Set<String> set = prop.stringPropertyNames();
        for (String key : set){
    
    
            //扎=160
            //巴=165
            //颖=168
            String value = prop.getProperty(key);
            System.out.println(key+"="+value);
            /*
            输入:#扎=160(巴-165) (颖 168)
            读取:不读取 (巴-165=)(颖=168)
            存储键值对的文件中,键与值默认的连接符号可以使用=,空格(其他符号)
            存储键值对的文件中,可以使用#进行注释,被注释的键值对不会再被读取
             */
            /*prop.load(new FileInputStream("sxmz\\src\\com\\sxmz\\IoClass\\class01\\prop.txt"));
            使用字节流会产生乱码
             */
        }
    }

猜你喜欢

转载自blog.csdn.net/rzz65452064/article/details/113815439