JAVA-IO 流专题

1、文件

1.1 什么是文件

简而言之,文件就是保存数据的地方。

1.2 文件流

文件在程序中是以流的形式来操作的

流:数据在数据源(文件)和程序 (内存)之间经历的路径;

输入流:数据从数据源(文件)到程序(内存)的路径;

输出流:数据从程序(内存)到数据源(文件)的路径。

(注意:此文的输入和输出,都是以程序(内存)的角度来看的)

1.3 常见的文件操作

1.3.1 创建文件对象的相关构造器和方法
File(String)  //  根据路径构建一个File对象
File(File, String)  // 根据给定的父目录名和子文件名字字符串创建一个File对象
File(String, String)  // 根据父路径名和子路径名字符串创建一个File对象
File(URI) // 将URI转换成一个抽象路径名来创建File对象
1.3.2 文件的操作方法

部分常用方法

方法描述

public String getName()

返回由此抽象路径名表示的文件或目录的名称。

public String getParent()

返回此抽象路径名的父路径名的路径名字符串,如果此路径名没有指定父目录,则返回 null。

public String getAbsolutePath()

返回抽象路径名的绝对路径名字符串。

public boolean exists()

测试此抽象路径名表示的文件或目录是否存在。

public boolean isDirectory()

测试此抽象路径名表示的文件是否是一个目录。

public boolean isFile()

测试此抽象路径名表示的文件是否是一个标准文件。

public long length()

返回由此抽象路径名表示的文件的长度。

public boolean createNewFile() throws IOException

当且仅当不存在具有此抽象路径名指定的名称的文件时,原子地创建由此抽象路径名指定的一个新的空文件。

public boolean delete()

删除此抽象路径名表示的文件或目录。

1.3.3 目录的操作和删除

方法

描述

public boolean mkdir()

创建此抽象路径名指定的目录。只能创建一级目录。

public boolean mkdirs()

创建此抽象路径名指定的目录,包括创建必需但不存在的父目录,可以创建一级或者多级目录。

public boolean delete()

删除此抽象路径名表示的文件或目录。

2、IO流原理及流的分类

2.1 Java IO 流原理

1.I/O是Input/Output的缩写,I/O技术是非常实用的技术,用于处理数据传输。如读/写文件,网络通讯等.

2.Java程序中,对于数据的输入/输出操作以”流(stream)”的方式进行。

3.java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过方法输入或输出数据

4.输入input:读取外部数据(磁盘、光盘等存储设备的数据))到程序(内存)中。

5.输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中

2.2 流的分类

按操作数据单位不同分为:字节流(8 bit)二进制文件,字符流(按字符)文本文

按数据流的流向不同分为:输入流,输出流

按流的角色的不同分为:节点流,处理流/包装流

抽象基类

字节流

字符流

输入流

InputStream

Reader

输出流

OutputStream

Writer

Java的IO流共涉及40多个类,都是从以上4个抽象基类派生的,由这四个类派生出来的子类名称都是以其作为子类名后缀

3、IO流体系图及常用的类

3.1 IO流体系图

3.2 字节流--InputStream和OutputStream

处理文件以字节为单位进行,InputStream以字节为单位读取文件内容到程序(内存)中使用;OutputStream将数据以字节为单位从程序(内存)写入到文件(磁盘)中。

3.2.1 FileInputStream介绍
  1. 类图

演示FileInputStream的使用(字节输入流 文件 -> 程序)

  • 1、单个字节的读取,效率比较低;

// FileInputStream.read()  
@Test  
public void readFile01(){  
    String filePath = "F:\\hello.txt";  
    int readData = 0;  
    FileInputStream fileInputStream = null;  
    try {  
        //  创建 FileInputStream 对象,用于 读取文件  
        fileInputStream = new FileInputStream(filePath);  
  
        // 从该输入流中读取一个字节的数据,如果没有输入可用,此方法将阻止(有汉字就会出现乱码:一个汉字=3个字节)  
        // 如果返回 -1, 表示读取完毕  
        while ((readData = fileInputStream.read()) != -1){  
            System.out.print((char)readData);       //转成char显示  
        }  
    } catch (IOException e) {  
        e.printStackTrace();  
    }finally {  
        //  关闭文件流,释放资源  
        try {  
            fileInputStream.close();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
}
  • 2、使用read(byte[] )这个方法读取提高效率

//FileInputStream.read(byte[] b)  
@Test  
public void readFile02(){  
    String filePath = "F:\\hello.txt";  
    int readLen = 0;  
    // 字节数组  
    byte[] buf = new byte[8];    // 一次读取8个字节  
    FileInputStream fileInputStream = null;  
    try {  
        //  创建 FileInputStream 对象,用于 读取文件  
        fileInputStream = new FileInputStream(filePath);  
  
        // 一次从该输入流中读取8个字节的数据,如果没有输入可用,此方法将阻止(有汉字就会出现乱码:一个汉字=3个字节)  
        // 如果返回 -1, 表示读取完毕  
        //  如果读取正常,返回实际读取的字节数  
        while ((readLen = fileInputStream.read(buf)) != -1){  
            System.out.print(new String(buf, 0, readLen));       //转成char显示  
        }  
    } catch (IOException e) {  
        e.printStackTrace();  
    }finally {  
        //  关闭文件流,释放资源  
        try {  
            fileInputStream.close();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
}
3.2.2 FileOutputStream介绍

演示使用FileOutPutStream将数据写到文件中, 如果文件不存在,则创建该文件

@Test  
    public void writeFile(){  
        //  创建 FileOutPutStream对象  
        String filePath = "F:\\a.txt";  
        FileOutputStream fileOutputStream = null;  
  
        try {  
            //   得到 fileOutputStream对象  
            //  说明:   1.new FileOutputStream(filePath)  创建方式,当写入内容时,会覆盖原来的内容  
            //           2.new FileOutputStream(filePath, true)  创建方式,当写入内容时,会追加到文件后面  
//            fileOutputStream = new FileOutputStream(filePath);  
            fileOutputStream = new FileOutputStream(filePath, true);  
            //  写入一个字节  
//            fileOutputStream.write('H');  
            //  写入字符串  
            String str = "Hello,worldhcp!";   //str.getBytes():  可以把字符串转换为字节数组  
//            fileOutputStream.write(str.getBytes());  
            // fileOutputStream.write(byte[] b, int off, int len): 将len字节从位于偏移量 off的指定字节数组写入此文件输出流  
            fileOutputStream.write(str.getBytes(), 0, str.length());  
        } catch (IOException e) {  
            e.printStackTrace();  
        }finally {  
  
            try {  
                fileOutputStream.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
    }
3.2.3 FileCopy实例

应用举例:完成文件拷贝 C:\Users\ASUS\Pictures\1.jpg 拷贝到 F:\盘。

public static void main(String[] args) {  
    //1. 创建文件的输入流:将文件读入到程序  
    //2. 创建文件的输出流:将读入的数据写入到文件中  
    
    FileInputStream fileInputStream = null;  
    String sourcePath = "C:\\Users\\ASUS\\Pictures\\1.jpg";  
    FileOutputStream fileOutputStream = null;  
    String destPath = "F:\\1.jpg";  
    try {  
        fileInputStream = new FileInputStream(sourcePath);  
        fileOutputStream = new FileOutputStream(destPath);  
  
        // 定义一个字节数组,提高读取效率  
        byte[] buf = new byte[1024];  
        int readLen = 0;  
        while ((readLen = fileInputStream.read(buf)) != -1){ //读取1024个字节数据  
            //读取到之后,就写入到文件,边读边写  
            fileOutputStream.write(buf, 0, readLen);   // 一定要使用该方法,最后一次有可能读取不够1024  
        }  
        System.out.println("拷贝成功");  
    } catch (IOException e) {  
        e.printStackTrace();  
    }finally {  
        try {  
            //  关闭输入流和输出流 释放资源  
            if (fileInputStream != null){  
            fileInputStream.close();  
            }  
            if (fileOutputStream != null){  
                fileOutputStream.close();  
            }  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
}
3.2.4 BufferedInputStream和BufferedOutputStream
  1. 类图

  1. 介绍:

1).使用Buffered修饰的io流为处理流(包装流),处理流是“连接”在已存在的流(节点流或处理流)之上,为程序提供更为强大的读写功能,也更加灵活。

2).原理:在底层使用了==修饰器设计模式==(*将InputStream节点流或InputStream处理流==封装为该类的属性==*),从而达到消除不同节点流的实现差异(==实现多态==),也能提供更加方便的方法。

3).Buffered对象创建时,会创建一个内部缓冲区数组byte[] buf,实现缓冲输入/输出。

  1. 应用案例:编程完成图片的拷贝

public static void main(String[] args) {  
  
        //二进制文件、音频文件、图片  
        String srcPath = "C:\\Users\\ASUS\\Pictures\\1.jpg";  
        String destPath = "F:\\1.jpg";  

        BufferedOutputStream bufferedOutputStream = null;  
        BufferedInputStream bufferedInputStream = null;  
  
        try {  
            // 创建对象  
            bufferedInputStream = new BufferedInputStream(new FileInputStream(srcPath));  
            bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(destPath));  
  
            // 循环读取文件,并写入  
            byte[] data = new byte[1024];  
            int readLen = 0;  
            //  当返回-1  时就表示文件读取完毕  
            while ((readLen = bufferedInputStream.read(data)) != -1){  
                //  写入  
                bufferedOutputStream.write(data, 0, readLen);  
            }  
            System.out.println("文件拷贝成功!");  
        } catch (IOException e) {  
            e.printStackTrace();  
        }finally {  
            // 关闭流外层  
            try {  
                if (bufferedInputStream != null)  
                    bufferedInputStream.close();  
                if (bufferedOutputStream != null)  
                    bufferedOutputStream.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
    }
3.2.5 对象流ObjectInputStream和ObjectOutputStream
  1. 类图

  1. 序列化和反序列化

序列化:就是在保存数据时,数据的值和数据类型都保存;

反序列化:将序列化后的数据进行恢复,恢复数据的值和数据类型;

(注:需要让某个对象支持序列化机制,必须让其类是可序列化的,某个类可序列化,即该类必须实现Serializable或者Externalizeble两个接口之一,推荐实现Serializable接口,因为该接口没有方法不需要实现。)

  1. 对象流的功能:提供了对基本类型或引用类型的序列化和反序列化的方法

ObjectOutputStream:提供了序列化功能

ObjectInputStream:提供了反序列化功能

  1. 代码示例:

(1)使用ObjectOutputStream序列化基本数据类型和一个Dog对象(name, age),并保存到data.dat文件中。

public static void main(String[] args) throws Exception {  
  
    //  序列化后,保存的文件格式,不是纯文本,而是按照他的格式来保存  
    String filePath = "F:\\data.dat";  
  
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));  
  
    //  序列化数据到  F:\data.dat    oos.writeInt(100);   // int自动装箱 -> Integer(实现了 Serializable 接口)  
    oos.writeBoolean(true);   //boolean自动装箱 -> Boolean(实现了 Serializable 接口)  
    oos.writeChar('a');  //char自动装箱 -> Character(实现了 Serializable 接口)  
    oos.writeDouble(9.5);  // double自动装箱 -> Double(实现了 Serializable 接口)  
    oos.writeUTF("新货的教育");   //String实现了 Serializable 接口  
  
    //  保存一个dog对象  必须进行实现Serializable 接口  才能序列化  
    oos.writeObject(new Dog("旺财", 10, "白色", "日本"));  
  
    oos.close();  
    System.out.println("数据保存完毕(序列化形式)");  
  
}

(2)使用ObjectInputStream读取data.dat,并反序列化恢复数据。

public static void main(String[] args) throws Exception {  
    // 反序列化的文件  
    String filePath = "F:\\data.dat";  
  
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));  
  
    //  读取  
    //  反序列化的顺序需要和你保存数据(序列化)的顺序一致  
    //  否则会出现异常  
  
    System.out.println(ois.readInt());  
    System.out.println(ois.readBoolean());  
    System.out.println(ois.readChar());  
    System.out.println(ois.readDouble());  
    System.out.println(ois.readUTF());  
    //  dog 的编译类型是 Object , dog的运行类型是 Dog    Object dog = ois.readObject();  
    System.out.println("运行类型:"+ dog.getClass());  
    System.out.println("dog信息:" + dog);   // 底层 Object -> Dog  
    //  这里特别重要的细节:  
  
    //  1. 如果我们洗完调用Dog的方法,需要向下转型  
    //  2. 需要我们将Dog类放到能够引用到该类才行   这样才能解析  
    Dog dog1 = (Dog)dog;  
    System.out.println(dog1.getName());  
  
    //  关闭流,关闭外层流即可,底层会关闭 FileInputStream    ois.close();  
}
  1. 注意事项

(1)反序列化的顺序要和序列化的顺序一致;

(2)要求序列化或反序列化的对象,需要实现Serializable接口;

(3)序列化对象时,默认将里面所有属性都进行序列化,除了static或transient修饰的成员;

(4)序列化对象时,要求里面属性的类型也需要实现序列化接口;

(5)序列化具有可继承行,即某类已经实现了序列化,则它的所有子类也默认实现了序列化。

3.3 字符流--Reader和Writer

处理文件以字符为单位进行,Reader以字符为单位读取文件内容到程序(内存)中使用;Writer将数据以字符为单位从程序(内存)写入到文件(磁盘)中。

3.3.1 FileReader和FileWriter
  1. 类图

  1. FileReader常用方法:

方法

描述

new FileReader(File/String)

创建一个FileReader对象

public int read() throws IOException

读取单个字符,返回一个int型变量代表读取到的字符

public int read(char [] c, int offset, int len)

读取字符到c数组,返回读取到字符的个数,如果到文件末尾返回-1

  1. FileWriter常用方法:

方法

描述

new FileWriter(File/String)

创建一个FileWriter对象,覆盖模式(相当于流的指针在首端)

new FileWriter(File/String, true)

创建一个FileWriter对象,追加模式(相当于流的指针在尾端)

public void write(int c) throws IOException

写入单个字符c。

public void write(char [] c, int offset, int len)

写入字符数组中开始为offset长度为len的某一部分。

public void write(String s, int offset, int len)

写入字符串中开始为offset长度为len的某一部分。

(注意:FileWriter使用后,必须要关闭close或刷新flush,否则写入不到指定的文件)

  1. FileReader和FileWriter案例

1)使用 FileReader 从 story.txt 读取内容,并显示

/*   单个字符读取文件 FileReader.read()  */
 @Test  
public void readFile01(){  
  
    String filePath = "F:\\story.txt";  
    FileReader fileReader = null;  
    int data = 0;  
    // 1. 创建FileReader 对象  
  
    try {  
        fileReader = new FileReader(filePath);  
  
        // 循环读取  使用read(),单个字符读取  
        while ((data = fileReader.read()) != -1){  
            System.out.print((char)data);  
        }  
    } catch (IOException e) {  
        e.printStackTrace();  
    }finally {  
        try {  
            fileReader.close();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
}  
  
  
/* 使用字符数组读取文件  FileReader.read(char[])  */
 @Test  
public void readFile02(){  
  
    String filePath = "F:\\story.txt";  
    FileReader fileReader = null;  
    int readLen = 0;  
    char[] buf = new char[8];  
    // 1. 创建FileReader 对象  
    try {  
        fileReader = new FileReader(filePath);  
  
        // 循环读取  使用read(char[]),读取一个字符数组,返回的是实际读取到的字符数  
        //  如果返回-1,说明到文件结束了  
        while ((readLen = fileReader.read(buf)) != -1){  
            System.out.print(new String(buf, 0, readLen));  
        }  
    } catch (IOException e) {  
        e.printStackTrace();  
    }finally {  
        try {  
            fileReader.close();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
}

2)使用 FileWriter 将 “风雨之后,定见彩虹” 写入到 note.txt 文件中, 注意细节.

public static void main(String[] args) {  
        String filePath = "F:\\note.txt";  
        // 创建FileWriter对象  
        FileWriter fileWriter = null;  
        char[] chars = {'a', 'b', 'c', 'd'};  
  
        try {  
            fileWriter = new FileWriter(filePath);  // 以覆盖的方式写入  
            // write():写入单个字符  
//            fileWriter.write('H');  
            //write(char[]): 写入指定字符数组  
//            fileWriter.write(chars);  
            //write(char[] , off, len):写入指定数组的指定部分  
//            fileWriter.write("智能教育:".toCharArray(), 0, 3);  
            // write(String): 写入整个字符串  
//            fileWriter.write("你好, 北京~");  
            // write(String, off, len):写入字符串的指定部分  
            fileWriter.write("北京, 天津", 0, 2);  
        } catch (IOException e) {  
            e.printStackTrace();  
        }finally {  
            // 对于FileWriter, 一定要关闭流, 或者flush才能真正的把数据写入到文件  
            /*  看源码  
           try {  
				//fileWriter.flush();  
                // 关闭文件流: 等价于 flush() +  关闭  
                fileWriter.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
            System.out.println("程序结束...");  
        }  
    }
3.3.2 处理流BufferedReader和BufferedWriter

应用案例:

  1. 使用BufferedReader读取文本文件,并显示在控制台

//  读取文本文件,并显示在控制台  
public static void main(String[] args) throws Exception{  
    String filePath = "F:\\story.txt";  
  
    //  创建BufferedReader 对象  
    BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));  
    // 读取  
    String line;  // 按行读取,效率高  
    //  1.bufferedReader.readLine()按行读取,当文件读取完毕返回为null  
    while ((line = bufferedReader.readLine()) != null){  
        System.out.println(line);  
    }  
  
    // 关闭流,  这里注意,只需要关闭BufferedReader,因为底层会自动的去关闭  节点流  
	bufferedReader.close();  
}
  1. 使用BufferedWriter将“hello, java", 写入到文件中

public static void main(String[] args) throws IOException {  
  
    String filePath = "F:\\ok.txt";  
    // 创建对象  BufferedWriter(new FileWriter(filePath))覆盖的方式  
    //BufferedWriter(new FileWriter(filePath), true)  以追加的方式写入  
    BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath, true));  
  
    bufferedWriter.write("hello, java!");  
    bufferedWriter.newLine();   //  插入一个和系统相关的换行  
    
    bufferedWriter.write("hello, java!");   
    bufferedWriter.newLine();  //  插入一个和系统相关的换行
  
    //  关闭外层包装流即可,传入的FileWriter会底层自动关闭  
    bufferedWriter.close();  
}
  1. 综合使用BufferedReader和BufferedWriter完成文本文件拷贝,注意编码问题

public static void main(String[] args) throws IOException {  
    // 说明  
    //  1.BufferedReader和BufferedWriter 是按照字符操作的  
    //  2.不要去操作二进制文件,可能造成文件损坏  
  
    //  将文件F:\ok.txt拷贝到F:\demo\ok.txt  
    String srcFilePath = "F:\\ok.txt";  
    String destFilePath = "F:\\ok1.txt";  
    // 创建对象  
    FileReader fileReader = new FileReader(srcFilePath);  
    FileWriter fileWriter = new FileWriter(destFilePath);  
    BufferedReader bufferedReader = new BufferedReader(fileReader);  
    BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);  
  
    String line;  //读取数据  
    while ((line = bufferedReader.readLine())!= null){  // 读取一行时不读取换行符  
        //  每读取一行,就写入  
        bufferedWriter.write(line);  
        //  插入一个换行符  
        bufferedWriter.newLine();  
    }  
  
    // 关闭流  
    bufferedReader.close();  
    bufferedWriter.close();  
  
    System.out.println("拷贝完毕!");  
}
3.3.3 转换流-InputStreamReader和OutputStreamWriter
  1. 引入:读取文件时出现乱码问题

    public static void main(String[] args) throws IOException {  
        //  读取  F:\\a.txt 文件  到程序  
        //  1. 创建字符输入流   BufferedReader(处理流)  
        //  2. 使用BufferedReader  对象读取a.txt  
        //  3. 默认情况下,读取文件是按照UTF-8编码读取的  
        //  4. a1.txt 的编码为gbk,输出就乱码
  
        String filePath = "F:\\a1.txt";  
        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));  
  
        String data;  
        while ((data = bufferedReader.readLine()) != null){  
            System.out.println(data);  
        }  
  
        if (bufferedReader != null){  
            bufferedReader.close();  
        }  
        System.out.println("文件读取完毕...");  
    }
  1. 介绍:

1)InputStreamReader:是Reader的子类,可以将InputStream(字节流)包装成Reader(字符流);

2)OutputStreamWriter:是Writer的子类,实现将OutputStream(字节流)包装成Writer(字符流);

3)当处理纯文本数据时,如果使用字符流效率更高,并且可以有效解决中文问题,所以建议将字节流转换为字符流;

4)可以在使用时指定编码格式(比如utf-8、gbk、gb2312、ISO8859-1等)。

  1. 案例

1.编程将字节流FileInputStream转换(包装)成字符流InputStreamReader,利用BufferedReader对文件进行读取(==按照gbk格式==)。

public static void main(String[] args) throws IOException {  
        String filePath = "F:\\a.txt";  
  
        // 1.把 FileInputStream 转成了  InputStreamReader  
        // 2.并且制定了编码  gbk//
  //InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), "gbk");  
//        //  3.把InputStreamReader  传入   BufferedReader
//		BufferedReader br = new BufferedReader(isr);  
  
        //  可以将1,2和3合在一起写  
        BufferedReader br = new BufferedReader(  
                                new InputStreamReader(  
                                        new FileInputStream(filePath), "gbk"));  
  
        //  4.再进行读取  
        String data;  
        while ((data = br.readLine()) != null){  
            System.out.println(data);  
        }  
        //  5.关闭外层流即可  
        if (br != null){  
            br.close();  
        }  
        System.out.println("读取完毕...");  
    }

2.编程将字节流FileOutputStream转换(包装)成字符流OutputStreamWriter,对文件进行写入(按照gbk格式)

public static void main(String[] args) throws IOException {  
    //  创建  
    String filePath = "F:\\a.txt";  
    BufferedWriter bw = new BufferedWriter(
						    new OutputStreamWriter(
							    new FileOutputStream(filePath), "gbk"));  
  
    //  写入  
    String data = "我是yjx!abacnskjd:”";  
    bw.write(data);  
    bw.newLine();  
  
    // 关闭外层流  
    bw.close();  
  
    System.out.println("写入完毕 ");  
}

3.4 标准输入输出流

  1. 基本介绍

介绍: 类型 默认设备

System.in 标准输入 InputStream 键盘

System.out 标准输出 OutputStream 显示器

  1. 案例

public static void main(String[] args) {  
    // System 类的 public static final InputStream in;  
    //  System.in  编译类型   InputStream 
    //  System.in  运行类型   BufferedInputStream
    // 表示标准输入  键盘  
    System.out.println(System.in.getClass());  
  
    //  System.out  编译类型  public static final PrintStream out;
	//  System.out  运行类型  PrintStream
	//  表示标准输出  显示器  
    System.out.println(System.out.getClass());  
  
    System.out.println("hello");  
  
    Scanner scanner = new Scanner(System.in);  
    System.out.println("请输入内容:");  
    String next = scanner.next();  
    System.out.println("next=" + next);  
}

3.5 打印流-PrintStream和PrintWriter

打印流只有输出流,没有输入流

public static void main(String[] args) throws IOException {  
    //  System.out  的类型就是  PrintStream 
   PrintStream out = System.out;  
    //  在默认情况下,PrintStream 输出数据的位置是 标准输出,即显示器  
    /*  
    *   底层代码分析:  
    *    public void print(String s) {            this.write(String.valueOf(s));         }    * */
	out.println("john., hello");  
    //  因为print底层使用的是write, 所以我们可以直接调用write进行打印/输出  
    out.write("你好,hello\n".getBytes());  
  
    // 我们也可以去修改打印输出流的 位置/ 设备  
    //  修改System输出到F:\f1.txt文件中  
    System.setOut(new PrintStream("F:\\f1.txt"));  
    //  输出到   F:\f1.txt  文件中  
    System.out.println("hello, 打印到F:\\f1.txt文件中去了");  
  
    out.close();  
}

4、Properties类

4.1 类图

4.2介绍

Properties类:专门用于读写配置文件的集合类

配置文件的格式:键=值

注意:键值对不需要有空格,值不需要用引号括起来,默认类型是String

4.3 常见方法

new Properties(): 创建Properties对象

load(InputStream/Reader):加载配置文件的键值对到Properties对象

list(PrintStream/PrintWriter):将数据显示到指定设备

getProperty(String):根据键获取值

setProperty(key, value):设置键值对到Properties对象,存在键就修改值,否则创建键值对

store(OutputStream/Writer):将Properties中的键值对存储到配置文件中,在idea中,保存信息到配置文件,如果含有中文,会存储为unicode码

4.4 案例

public static void main(String[] args) throws IOException {  
  
    //   使用 Properties类 来读取mysql.properties文件  
  
    //  1.创建Properties对象  
    Properties properties = new Properties();  
    //  2.加载指定配置文件  
    properties.load(new FileInputStream("src\\mysql.properties"));  
  
    //  3.把key-value显示到控制台  
    properties.list(System.out);  
  
    //  4.根据key获取对应的值  
    String ip = properties.getProperty("ip");  
    String user = properties.getProperty("user");  
    String pwd = properties.getProperty("pwd");  
  
    System.out.println("ip地址是:" + ip);  
    System.out.println("用户名为:" + user);  
    System.out.println("密码是:" + pwd);  
  
        // 创建  k - v
        // 如果文件中没有key就是创建;如果文件中已经有该key就是修改value  
        //  Properties 父类是 HashTable, 底层就是HashTable 的核心方法  put(key, value)         
        properties.setProperty("charset", "utf8");  
        properties.setProperty("user", "yjx");   //  注意保存的,是中文对应的 Unicode码值  
        properties.setProperty("pwd", "adc111");  
        properties.setProperty("pwd", "88888");   // 修改  
  
        // 将  k - v 存储文件中即可  
		// properties.store(new FileWriter("src\\mysql2.properties"), 
		//"使用Properties创建文件");  使用字符流直接保存中文  
        properties.store(new FileOutputStream("src\\mysql2.properties"), "使用Properties创建文件");  // 使用字节流中文保存为Unicode码值  
  
        System.out.println("保存配置文件成功~");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值