java的IO流

java 的IO流

一、什么是IO流?

1.1 IO流的概述

1.2 IO流的分类

存在多种分类方式

​ 1)当根据流的方向来分类,

输入流:以内存为参照物,往内存中进去叫做输入(或者叫做读),

输出流:往内存中出来叫做输出(或者叫做写)

​ 2)按照读取数据方式的不同来进行分类:

字节流:一次读取一个字节byte,等同于一次读取八个二进制位,这种流是万能的,可以读取任何的文件

字符流:一次读取一个字符,这种流是为了方便读取普通的文本文件而存在的,只能够读取纯文本文件txt

1.3学习目的

java的IO流都是在,java.io.*;

怎么new对象

怎么调用流对象的方法

二、流的四大家族

java.io.InputStream 字节输入流

java.io.OutputStream 字节输出流

java.io.Reader 字符输入流

java.io.Writer 字符输出流

注意:java中以stream结尾的都是字节流,以Reader/Writer结尾的都是字符流

上面的类都是抽象的

2.1所有的流都实现了

​ java.io.Closeable接口: 都是可关闭的,都有close()方法,使用完毕后需要关闭

​ java.io.Flushable接口:都是可刷新的.,都有flush()方法,输出流在最终输出后,一定要flush()刷新,刷新表示将管道中剩余的数据输出(清空管道)

三、java.io下面需要掌握的16个流

文件专属:
java.io.FileInputStream(掌握) 对byte进行操作
java.io.FileOutputStream(掌握)对byte进行操作
java.io.FileReader 对char进行操作
java.io.FileWriter 对char进行操作

转换流:(将字节流转换成字符流)
java.io.InputStreamReader
java.io.OutputStreamWriter

缓冲流专属:
java.io.BufferedReader
java.io.BufferedWriter
java.io.BufferedInputStream
java.io.BufferedOutputStream

数据流专属:
java.io.DataInputStream
java.io.DataOutputStream

标准输出流:
java.io.PrintWriter
java.io.PrintStream(掌握)

对象专属流:
java.io.ObjectInputStream(掌握)
java.io.ObjectOutputStream(掌握)

四、FileInStream

java.io.FileInputStream

1.文件字节输入流,万能的流,任何类型的文件都可以采用

2.字节的方式,完成输入的操作(硬盘–>内存)

4.1创建对象的操作

try {
    FileInputStream f1 = new FileInputStream("D:\\temp.txt");
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

会出现编译时异常,需要在编译时处理。

由于\ 表示的是转义所以使用\\表示一个,还可使用/。

都是采用了绝对路径的方式,还可以使用相对路径。

4.2关闭流的操作

finally { // 在finally语句块中关闭流,前提是流不为空
    if (f1 != null){ // 避免空指针异常
        try {
            f1.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4.3 读取数据

读取有关的方法 read(),每次调用此方法就读取一次数据(数据是字节类型)

public  int  read() throws IOException  

读取到文件的末尾返回-1

//开始读取
int date = f1.read(); // 读取到的返回值是字节本身

使用循环输出数据,每次读取一个字节

f1 = new FileInputStream("F:\\temp.txt");
int date = 0;
while ((date = f1.read())!= -1){
   System.out.println(date);
}

一次读取多个字节

int read(byte[] b) 输入流中将最多b.length个字节数据读入一个byte数组.

int  read(byte[] b) // 返回的是读取字节的数量
// 读取到的字节是几个就返回对于的数据的个数

减少硬盘和内存的交互,提高程序的执行效率,

往byte数组中读

出现的问题:

当我们保存的数据有6个时,byte数组每次读取4个,当第一次读取完毕后还剩下2个字节,继续读取的时候读取出来的两个数据会覆盖byte数组0,1下标的之前读取的信息,但是下标3,4的数据依旧存在.

所以为了避免将之前读取的数据再次输出的情况,将byte数组转换为字符串的时候使用字符串构造方法,传入byte数组,起始位置,结束位置

4.4最终形态的代码

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

public class one {
    public static void main(String[] args) {
        FileInputStream f1 = null;
        try {

            f1 = new FileInputStream("F:\\temp.txt");

            byte [] by = new byte[6];
            int index = 0;
            while ( (index = f1.read(by)) != -1){
                System.out.println(new String(by,0,index));
                //使用字符串构造方法,传入byte数组,起始位置,结束位置
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally { // 在finally语句块中关闭流,前提是流不为空
            if (f1 != null){ // 避免空指针异常
                try {
                    f1.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

4.5其他的方法

int  available() 返回流当中剩余的字节数量
long  skip(long n) 跳过几个字节不读

1) available()

f1 = new FileInputStream("F:\\temp.txt");

f1.read();

System.out.println("还剩下的字节数" + f1.available());

用法

f1 = new FileInputStream("F:\\temp.txt");

//available方法的用处
byte [] by = new byte[f1.available()];

f1.read(by);

//不需要循环,直接一次输出完
System.out.println(new String(by));

不适用于大文件,因为byte数组不能够太大.

2) skip跳几个字节

f1 = new FileInputStream("F:\\temp.txt");

f1.skip(2); // 跳过两个字节开始读取

byte [] by = new byte[f1.available()];

f1.read(by);

System.out.println(new String(by)); // cdef

五、FileOutStream

文件字节输出流,内存–>硬盘

public static void main(String[] args) {
    FileOutputStream f1 = null;

    try {
        // 文件不存在会自动新建
        //true表示往文件添加元素,默认位false
        f1 = new FileOutputStream("F:\\temp.txt", true);
        
        byte [] by = {97, 98, 99};

        //开始写入全部数据
        f1.write(by);

        //写入部分数据
        f1.write(by,0,2);

        // 写入字符串
        String s = "恐怖如斯";
        byte [] bb = s.getBytes();
        f1.write(bb);

        f1.flush();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }finally {
        if (f1 != null){
            try {
                f1.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

六、字节文件的复制

FileInputStream,与FileOutStream都是对byte数组进行操作

try catch的时候要分开操作,因为当一个出现问题的时候,另一个无法关闭

public static void main(String[] args) {
    FileInputStream read = null;
    FileOutputStream write = null;

    try {
        read = new FileInputStream("F:\\temp.txt");
        write  = new FileOutputStream("F:\\te.txt");

        int index = 0;
        byte [] by = new byte[1024 * 124]; // 1024 == 1kb, 1024 * 1024 = 1M

        while ((index = read.read(by)) != -1){
            write.write(by,0,index);
        }

        write.flush();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 继续try  catch的时候要分开操作,因为当一个出现问题的时候,另一个无法关闭
       if (read != null){
           try {
               read.close();
           } catch (IOException e) {
               e.printStackTrace();
           }
       }
       if (write != null){
           try {
               write.close();
           } catch (IOException e) {
               e.printStackTrace();
           }
       }
    }

}

七、FileReader

文件字符输入流,只能够读取普通文本,word文档不属于普通文本

能够使用记事本编译的都是普通文本文件

读取文本内容时比较快捷方便

编码方式类似FileInStream,只不过使用的数组是char数组

public static void main(String[] args) {
    FileReader fileReader  = null;

    try {
        fileReader = new FileReader("F:\\temp.txt");
        int index = 0;
        char [] ch = new char[10];
        while (( index = fileReader.read(ch))!= -1){
            System.out.println(new String(ch, 0 , index));
        }
    }catch (FileNotFoundException e){
        e.printStackTrace();
    }catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (fileReader != null){
            try {
                fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

八、FileWriter

public static void main(String[] args) {
    FileWriter fileWriter = null;

    try {
        fileWriter = new FileWriter("F:\\hh.txt");
        char [] chars = new char[]{'无','语'};

        //写入字符数组,也可以是数组的一部分
        fileWriter.write(chars);

        //可以直接写入字符串
        fileWriter.write("哈哈哈");

        fileWriter.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }finally {
        if (fileWriter != null){
            try {
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

九、字符文件的复制

使用FileReader和FileWriter只可以拷贝普通文本文件

public static void main(String[] args) {
    FileReader fileReader = null;
    FileWriter fileWriter = null;

    try {
        fileReader = new FileReader("F:\\temp.txt");
        fileWriter = new FileWriter("F:\\tem.txt");
        int index = 0;
        char [] chars = new char[4];
        while ((index = fileReader.read(chars)) != -1){
            fileWriter.write(chars,0,index);
        }

        fileWriter.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (fileReader != null){
            try {
                fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (fileWriter != null){
            try {
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

十、带缓冲的流

之前的流都是需要使用byte或者char数组过渡数据,带缓冲的流可以直接操作

10.1 BufferedReader 带缓冲区的流

存在特殊的构造方法构,造方法需要传入FileReader的对象(字符流对应的对象).

bufferedReader = new BufferedReader(new FileReader("F:\\temp.txt"));

概念:如果构造方法需要传入流的话那么传入的流叫做节点流,外部包装的流叫做包装流(处理流),关闭流的话只需要关闭最外层,里面的节点流就会自动关闭

String  readLine() //每次读取一行数据,没有数据了返回null

读取一行的话 ,行后面的换行符没有读取出来

如果换行的话可能是System.out.println(…); 产生的换行

public static void main(String[] args) {
    BufferedReader bufferedReader = null;

    try {
        bufferedReader = new BufferedReader(new FileReader("F:\\temp.txt"));

        String s;

        // 读取一行的字符串
        s = bufferedReader.readLine();

        System.out.print(s);

        // readLine() 方法读取到文件末尾会返回一个null
        while ((s = bufferedReader.readLine()) != null){
            System.out.print(s);
        }


    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (bufferedReader != null){
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

10.2 BufferWriter 带缓冲的字符输出流

public static void main(String[] args) {
    BufferedWriter bufferedWriter = null;

    try {
        bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("F:\\temp.txt")));
        //使用转换流,将字节流转换为字符流
        
        bufferedWriter.write("你好啊python");

        
        
        bufferedWriter.flush();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }finally {
        if (bufferedWriter != null){
            try {
                bufferedWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

十一、转换流

InputStreamReader, 将读取的字节流,转换为字符流

OutPutStreamWriter 将输出的字节流转为字符流

InputStreamReader

应用场景

当缓存流的构造方法只能够传入对应的字符流的时候,如果没有字符流的情况,可以将字节流,通过转换流转换为字符流.

构造方法:

InputStreamReader(InputStream in)
// 插入一个使用默认字符集的 InputStreamReader

InputStreamReader(InputStream in, Charset cs)
//创建使用给定字符集的InputStreamReader

InputStreamReader(InputStream in, CharsetDecoder dec)
//创建使用给定字符集解码器的InputStreamReader

InputStreamReader(InputStream in, String s)
//创建使用指定字符集的InputStreamReader

案例:

public static void main(String[] args) {
    BufferedReader bufferedReader = null;

    try {
        FileInputStream fileImageInputStream = new FileInputStream("F:\\temp.txt"); // 字节流

        InputStreamReader buf = new InputStreamReader(fileImageInputStream);//转换流:将字节流-->字符流

        bufferedReader = new BufferedReader(buf); // 缓存流

        String s;

        // 读取一行的字符串
        s = bufferedReader.readLine();

        System.out.print(s);

        // readLine() 方法读取到文件末尾会返回一个null
        while ((s = bufferedReader.readLine()) != null){
            System.out.print(s);
        }


    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (bufferedReader != null){
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

十二、数据专属流

java.io.DataOutputStream:

数据专属的流

可以将数据连同数据的类型一同写入文档,

这个文件不是普通文本文件(记事本打不开)

public DataOutputStream(OutputStream out) // 传入字节输出流
public static void main(String[] args) {
    DataOutputStream dataOutputStream = null;

    try {
        dataOutputStream = new DataOutputStream(new FileOutputStream("F:\\temp.txt"));

        //写数据
        byte b = 10;
        short s = 11;
        int i = 12;
        long l = 13;
        float f = 14.0f;
        double d = 14.23;
        boolean n = false;
        char c = 'a';

        dataOutputStream.writeByte(b);
        dataOutputStream.writeShort(s);
        dataOutputStream.writeInt(i);
        dataOutputStream.writeLong(l);
        dataOutputStream.writeFloat(f);
        dataOutputStream.writeDouble(d);
        dataOutputStream.writeBoolean(n);
        dataOutputStream.writeChar(c);

        dataOutputStream.flush();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (dataOutputStream != null){
            try {
                dataOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

注意:写入的数据记事本打开是乱码无法识别,像加密后的文件.

使用数据流写入的文件,必须使用数据读取,读取的时候需要知道加密规则,也就是写入的顺序和读取的类型

java.io.DataInputStream

public static void main(String[] args) {
    DataInputStream dataInputStream = null;

    try {
        dataInputStream = new DataInputStream(new FileInputStream("F:\\temp.txt"));
        

        System.out.println(dataInputStream.readByte());
        System.out.println(dataInputStream.readShort());
        System.out.println(dataInputStream.readInt());
        System.out.println(dataInputStream.readLong());
        System.out.println(dataInputStream.readFloat());
        System.out.println(dataInputStream.readDouble());
        System.out.println(dataInputStream.readBoolean());
        System.out.println(dataInputStream.readChar());
        
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (dataInputStream != null){
            try {
                dataInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

十三、标准输出流

java.io.PrintStream: 标准的字节输出流,默认输出到控制台

System.out.println("哈哈哈"); // 联合起来的写法

PrintStream pr = System.out; // 分开的写法
pr.println("a");
pr.println("b");
pr.print("c");
pr.print("c");

// 改变输出方向
//标准输出流不再输出数据到看控制台,而是指定的log文件
try {
    PrintStream PrintStream = new PrintStream(new FileOutputStream("log"));
    // 修改输出方向,将输出方向修改到log文件
    System.setOut(PrintStream);

    PrintStream.print("hello java");
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

不需要关闭流

可以改变输出方向,将输出的数据保存到文件

File类

java.lang.Object–> java.io.File

File不是一个流,是无法完成文件的读和写的.

File对象代表的什么?

是文件和目录路径名的抽象表现新式

一个File对象有可能对应的是目录,也可能是文件

File只是一个路径的抽象表现形式

File类的常用方法

创建对象
File file = new File("F:\\temp.txt");

判断指定的文件是否存在

System.out.println(file.exists());

文件不存在就以文件夹的形似创建出来


if (file.exists()){
    try {
        file.createNewFile(); // 创建文件夹
    } catch (IOException e) {
        e.printStackTrace();
    }
}

如果文件不存在就以目录的形似创建出来


if (file.exists()){
    file.mkdir();
}

创建多重目录

File file1 = new File("F:\\a\\b\\c");
if (!file1.exists()){
    file1.mkdirs();
}

获取文件的父路径

String str = file1.getParent();
System.out.println(str);  //  F:\a\b

获取绝对路径

String abs = file1.getAbsolutePath();
System.out.println(abs);

获取文件名字

String sname = file1.getName();
System.out.println(sname);

判断是否是目录

boolean mkd = file1.isDirectory();
System.out.println(mkd);

判断是否是一个文件

System.out.println(file1.isFile());

获取文件最后一次修改时间

long ll = file1.lastModified();// 毫秒,从1970年到现在的总毫秒数
// 将总毫秒数转化为日期
Date date = new Date(ll);
SimpleDateFormat sim = new SimpleDateFormat("yy-MM-dd HH:mm:ss SSS");
String lasttime = sim.format(date);
System.out.println(lasttime);

获取文件大小

System.out.println(file1.length()); // 单位字节

获取当前目录下面的所有子目录

// File  []  listFiles()
File file2 = new File("F:\\各种文件的jar包");
File [] lis = file2.listFiles();//获取目录文件数组
for (File fi : lis){
    System.out.println(fi.getName());//输出文件的名字
}

目录的拷贝

public static void main(String[] args) {

    //拷贝源
    File file1 = new File("E:\\music\\中文歌\\汪苏泷");
    // 拷贝目标
    File file2 = new File("F:\\mus");

    CopyAll(file1, file2);
}

public static void CopyAll(File file1, File file2){
    //如果需要复制是文件不是目录的时候停止操作
    if (file1.isFile()){
        //是文件的话需要拷贝,边读边写
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;

        try {
            fileInputStream = new FileInputStream(file1); // 可以直接传入文件
            String str = file1.getAbsolutePath().substring(2);
            fileOutputStream = new FileOutputStream(file2.getAbsoluteFile() + str);

            int index = 0;
            byte [] bytes = new byte[1024 * 1024];
            while (( index = fileInputStream.read(bytes)) != -1){
                fileOutputStream.write(bytes,0,index);
            }

            fileOutputStream.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (fileInputStream != null){
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fileOutputStream != null){
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return;//是文件就递归结束,如果是目录的话就执行下面的直到打开的为文件即可
    }

    //获取源下面的子目录
    File [] list_file = file1.listFiles();
    for (File f : list_file){

        // 如果需要拷贝的文件是一个目录的话需要再目标文件创建对应的目录
        if(file1.isDirectory()){
            String srcDir = file1.getAbsolutePath();
            String new_file_name = file2.getAbsolutePath() + srcDir.substring(2);
            System.out.println(new_file_name);
            File newFile = new File(new_file_name);
            if (!newFile.exists()){
                newFile.mkdirs(); // 以多重目录的形式创建出来
            }
        }

        //递归调用,当里面是文件的时候继续调用方法
        CopyAll(f,file2);

    }
}

十四、对象流

ObjectInputStream

ObjectOutputStream

序列化(Serialize):java对象存储到文件中,将java对象的状态保存下来的过程

反序列化(DeSerialize): 指将硬盘上的数据恢复到内存当中,恢复为java对象

参与序列化和反序列化必须实现接口implements Serializable,

只是一个标志性接口,接口里面什么代码都没有,起标志作用,java虚拟机看见这个接口,可能会对这个类进行特殊处理

java中的接口

java中的接口分为两类:

普通接口:

标志性接口:方法里面没有内容,标志接口是给java虚拟机参考的,java虚拟机 会生成一个序列化版本号

1)序列化

public class one {
    public static void main(String[] args) {
        student s1 = new student(12,"中");
        ObjectOutputStream one = null;
        //序列化
        try {
           one = new ObjectOutputStream(new FileOutputStream("F:\\stu"));

           //序列化
           one.writeObject(s1);

           one.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (one != null){
                try {
                    one.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

// 一个实现了Serializable的类
class student implements Serializable {
    private int no;
    private String name;

    public student(int no, String name) {
        this.no = no;
        this.name = name;
    }

    public student() {
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "student{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }
}

2)反序列化

ObjectInputStream ob = null;
try {
    ob = new ObjectInputStream(new FileInputStream("F:\\stu"));

    //反序列化
    student stu = (student) ob.readObject();
    // 输出保存在对象里面的数据
    System.out.println(stu.getName());
    System.out.println(stu.getNo());
    
} catch (IOException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}finally {
    if (ob != null){
        try {
            ob.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3)序列化多个对象

可以将对象放入到集合中,然后序列化集合

4)部分序列化

对于不需要使用序列化的位置,使用 transient 修饰,表示游离的不参与序列化.

不参与序列化的属性,输出的话会输出默认值

class student implements Serializable {
    private transient int no; // no不参与序列化
    private String name;

    public student(int no, String name) {
        this.no = no;
        this.name = name;
    }

    public student() {
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

5) 序列化版本号

作用:区分类

java虚拟机检测到标志性接口Serializable 会生成序列号.

当十年前将一个对象序列化保存到硬盘里面,十年后对象的模板类class文件已经发生改变,java虚拟机生成的序列化版本号也会发生相应的改变。进行反序列化的时候如果两次的序列化版本号不一样会报错…

java中采用什么来区分序列化版本号?

​ 1.首先通过类名字进行比较,类名不一样,肯定不是同一个类

​ 2.类名字相同,通过序列化版本号区分

自动生成序列化版本号的缺陷

​ 1.后期不能够修改代码,一旦修改代码必然会重新编译 ,此时会生成新的序列化版本号,这个时候java虚拟机会认为这是一个全新的类

结论:

​ 凡是一个类实现了Serializable 接口,建议给该类设置一个不变的序列化版本号,

以后即使代码改变了,但是版本号不变,java虚拟机也会认为是同一个类,

设置序列化版本号

private static final long serialVersionUID = 1L;  // 自定义序列化版本号

java虚拟机识别一个类,先通过类名,如果类名字一致,在通过比较序列化版本号

class student implements Serializable {

    private static final long serialVersionUID = 1L; // 自定义序列化版本号

     int no;
     String name;

    public student(int no, String name) {
        this.no = no;
        this.name = name;
    }
}

自定义序列化版本号后就可以对类里面的内容进行修改

十五、IO 与 properties联合使用

IO流:文件的读和写

properties: key和value都是String类型

写一个文件,文件里面保存

username=zhang
userword=123

//key重复的话value会覆盖
//等号两边最好不要有空格
//也可以使冒号隔开,但是不建议使用

代码实现

需求,将文件里面的数据加载到对象中

public static void main(String[] args) {

    FileReader fileReader = null;
    try {
        //创建
        fileReader = new FileReader("F:\\temp.txt");

        //创建一个map集合
        Properties maps = new Properties();

        //调用Propertiesde的load方法,将文件里面的数据加载到集合中
        maps.load(fileReader);

        System.out.println(maps.get("username")); // zhang
        System.out.println(maps.get("userword")); // 123
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }finally {
        if (fileReader != null){
            try {
                fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

重点解读

程序中经常发生变化的信息,就保存到文件中动态的获取数据,只需要对文件继续修改,就可以拿到信息.

类似于以上机制的文件叫做配置文件,

如果拍照文件的格式为:

​ key1=value1

​ key2=value2

的时候称为:属性配置文件

.no = no;
this.name = name;
}
}


自定义序列化版本号后就可以对类里面的内容进行修改



## 十五、IO 与 properties联合使用

IO流:文件的读和写

properties: key和value都是String类型



写一个文件,文件里面保存

```java
username=zhang
userword=123

//key重复的话value会覆盖
//等号两边最好不要有空格
//也可以使冒号隔开,但是不建议使用

代码实现

需求,将文件里面的数据加载到对象中

public static void main(String[] args) {

    FileReader fileReader = null;
    try {
        //创建
        fileReader = new FileReader("F:\\temp.txt");

        //创建一个map集合
        Properties maps = new Properties();

        //调用Propertiesde的load方法,将文件里面的数据加载到集合中
        maps.load(fileReader);

        System.out.println(maps.get("username")); // zhang
        System.out.println(maps.get("userword")); // 123
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }finally {
        if (fileReader != null){
            try {
                fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

重点解读

程序中经常发生变化的信息,就保存到文件中动态的获取数据,只需要对文件继续修改,就可以拿到信息.

类似于以上机制的文件叫做配置文件,

如果拍照文件的格式为:

​ key1=value1

​ key2=value2

的时候称为:属性配置文件

java中属性配置文件要求以properties结尾不是必须的.

上一篇:Android安全防护防护———加密算法


下一篇:Java基础14-网络编程