java学习笔记-IO流(韩顺平)

1. 文件

1.1 概念

  • 什么是文件?

    文件,对我们来说并不陌生,文件是保存数据的地方,比如大家经常使用的word文档,txt文档,excel文件...都是文件。它既可以保存一张图片,也可以保存视频,声音...

  • 文件流

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

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

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

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

1.2 常用的文件操作

  • 相关方法

    new File(String pathname) //根据路径构建一个File对象

    new File(File parent,String child) //根据父目录文件 + 子路径构建

    new File(String parent,String child) //根据父目录 + 子路径构建

    createNewFile 创建新文件

    package com.mdklea.file;
    ​
    import org.junit.jupiter.api.Test;
    ​
    import java.io.File;
    import java.io.IOException;
    ​
    @SuppressWarnings({"all"})
    public class FileCreate {
        public static void main(String[] args) {
    ​
        }
    ​
    ​
        @Test
        //方式一
        public void create01()  {
            String filePath = "f:\\news1.txt";
            File file = new File(filePath);
    ​
            try {
                file.createNewFile();
                System.out.println("文件创建成功");
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    ​
        @Test
        //方式二
        public void create02() {
            File parentFile = new File("f:\\");
            String fileName = "news2.txt";
            //这里的file对象,在java程序中,只是一个对象
            //只有真正的执行了createNewFile方法,才会在磁盘创建该文件
            File file = new File(parentFile, fileName);
            try {
                file.createNewFile();
                System.out.println("文件创建成功");
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    ​
        @Test
        //方式三
        public void create03() {
            String parentPath = "f:\\";
            String fileName = "news3.txt";
            File file = new File(parentPath,fileName);
            try {
                file.createNewFile();
                System.out.println("创建成功!");
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
  • 获取文件相关信息

    getName、getAbsolutePath、getParent、length、exists、isFile、isDirectory

    package com.mdklea.file;
    ​
    import org.junit.jupiter.api.Test;
    ​
    import java.io.File;
    ​
    public class FileInformation {
        public static void main(String[] args) {
    ​
        }
        @Test
        //获取文件信息
        //getName、getAbsolutePath、getParent、length、exists、isFile、isDirectory
        public void info() {
            File file = new File("f:\\news1.txt");
            //获取文件名
            System.out.println("文件名" + file.getName());
            //获取绝对路径
            System.out.println("文件绝对路径" + file.getAbsoluteFile());
            //获取文件父级目录
            System.out.println("文件父级目录" + file.getParent());
            //获取文件字节大小
            System.out.println("文件大小(字节)" + file.length());
            //判断文件是否存在
            System.out.println("存在状态" + file.exists());
            //判断是不是一个文件/目录
            System.out.println(file.isFile() + " " + file.isDirectory());
        }
    }
  • 目录的操作和文件的删除

    mkdir创建一级目录、mkdirs创建多级目录、delete删除空目录或文件

    package com.mdklea.file;
    ​
    import org.junit.jupiter.api.Test;
    ​
    import java.io.File;
    @SuppressWarnings({"all"})
    public class Directory_ {
        public static void main(String[] args) {
    ​
        }
    ​
        @Test
        public void m1() {
            String filePash = "f:\\news1.txt";
            File file = new File(filePash);
            if (file.exists()) {
                if (file.delete()) {
                    System.out.println("删除成功");
                }else {
                    System.out.println("删除失败");
                }
            }else {
                System.out.println("该文件不存在");
            }
        }
    ​
    ​
        //判断F:\\demo02 是否存在,存在就删除,否则提示不存在
        //这里我们需要体会到,在java编程中,目录也被当作文件
        @Test
        public void m2() {
            String filePash = "f:\\demo02";
            File file = new File(filePash);
            if (file.exists()) {
                if (file.delete()) {
                    System.out.println("删除成功");
                }else {
                    System.out.println("删除失败");
                }
            }else {
                System.out.println("该目录不存在");
            }
        }
    ​
        @Test
        public void m3() {
            String directoryPash = "f:\\demo\\a\\b\\c";
            File file = new File(directoryPash);
            if (file.exists()) {
                System.out.println(directoryPash + " 存在...");
            }else {
                if (file.mkdirs()) {  //创建一级目录使用mkdir(),创建多级目录使用mkdirs()
                    System.out.println(directoryPash + " 创建成功!");
                }else {
                    System.out.println(directoryPash + " 创建失败!");
                }
            }
        }

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 流的分类

  • 按操作数据单位不同分为:字节流(8bit,二进制文件无损操作),字符流(按字符,文本文件效率较高)

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

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

  1. Java的IO流共涉及40多个类,实际上非常规则,都是从如上4个抽象基类派生的。

  2. 由这四个类派生出来的子类名称都是以其父类名为子类名后缀

3.IO流体系图-常用的类

3.1 IO流体系图

3.2 文件VS流

3.3 InputStream:字节输入流

  • InputStream 抽象类是所有类字节输入流的超类

  • InputStream 常用的子类

    1. FileInputStream:文件输入流

    2. BufferedInputStream:缓冲字节输入流

    3. ObjectInputStream:对象字节输入流

3.3.1 fileInputStream

package com.mdklea.file;
​
import org.junit.jupiter.api.Test;
​
import java.io.FileInputStream;
import java.io.IOException;
/*
单个字节的读取,效率比较低
-》使用read(byte[] b)读取
  */
@SuppressWarnings({"all"})
public class FileInputStream_ {
    public static void main(String[] args) {
​
    }
    @Test
    public void readFile01() {
        String filePath = "F:\\hello.txt";
        int readData = 0;
        FileInputStream fileInputStream = null;
        try {
            //创建FileInputStream 对象,用于读取 文件
            fileInputStream = new FileInputStream(filePath);
            //从该输入流读取一个字节的数据,如果没有输入可用,此方法将阻止
            //如果返回-1,表示读取完毕
            while ((readData = fileInputStream.read()) != -1) {
                System.out.print((char) readData);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            //关闭文件流,释放资源
            try {
                fileInputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    @Test
    public void readFile02() {
        String filePath = "F:\\hello.txt";
        int readData = 0;
        byte[] buf = new byte[8];//一次读取8个字节
        int readLen = 0;
        FileInputStream fileInputStream = null;
        try {
            //创建FileInputStream 对象,用于读取 文件
            fileInputStream = new FileInputStream(filePath);
            //从该输入流读取一个字节的数据,如果没有输入可用,此方法将阻止
            //如果返回-1,表示读取完毕
            //如果读取正常,返回实际读取的字节数
            while ((readLen = fileInputStream.read(buf)) != -1) {
                System.out.print(new String(buf,0,readLen));
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            //关闭文件流,释放资源
            try {
                fileInputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

3.4 OutputStream:字节输出流

3.3.2 fileOutputStream

package com.mdklea.file;
​
import org.junit.jupiter.api.Test;
​
import java.io.*;
​
@SuppressWarnings({"all"})
public class FileOutPutStream_ {
    public static void main(String[] args) {
​
    }
​
    /**
     * 演示使用FileOutputStream 将数据写到文件中,
     * 如果该文件不存在,将创建该文件
     */
    @Test
    public void writeFile01() {
        FileOutputStream fileOutPutStream = null;
        String filePash = "F:\\a.txt";
        String str = "Hello m1!";
​
        try {
            fileOutPutStream = new FileOutputStream(filePash,true);
            //fileOutPutStream.write(str.getBytes());
            //fileOutPutStream.write('b');
            fileOutPutStream.write(str.getBytes(),0,3);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                fileOutPutStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
  • FileOutputStream 应用实例

    package com.mdklea.file;
    ​
    import org.junit.jupiter.api.Test;
    ​
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    ​
    @SuppressWarnings({"all"})
    public class FileStreamTest {
        public static void main(String[] args) {
    ​
        }
    ​
        @Test
        public void method01() {
            FileInputStream fileInputStream = null;
            FileOutputStream fileOutputStream = null;
            String srcPath = "E:\\2.png";
            String destPath = "E:\\1.png";
            int readLen = 0;
            try {
                fileInputStream = new FileInputStream(srcPath);
                fileOutputStream = new FileOutputStream(destPath);
                byte[] bytes = new byte[1024];
                while ((readLen = fileInputStream.read(bytes)) != -1) {
                    //读取到后,就写入到文件,通过fileOutputStream
                    //即边读边写
                    fileOutputStream.write(bytes,0,readLen);
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }finally {
                try {
                    if (fileInputStream != null){
                        fileInputStream.close();
                    }
                    if (fileOutputStream != null) {
                        fileOutputStream.close();
                    }
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

3.5 FileReader 和 FileWriter 介绍

3.5.1 FileReader

FileReader 和 FileWriter 是字符流,即按照字符来操作io

FileReader相关方法

  1. new FileReader(File/String)

  2. read:每次读取单个字符,返回该字符,如果到文件末尾返回-1

  3. read(char[]) :批量读取多个字符到数组,返回读取到的字符数,如果到文件末尾返回-1

相关API

  1. new String(char[]):将char[] 转换成String

  2. new String(char[],off,len):将char[] 的指定部分转换成String

package com.mdklea.file;
​
import org.junit.jupiter.api.Test;
​
import java.io.FileReader;
import java.io.IOException;
​
@SuppressWarnings({"all"})
public class FileReader_ {
    public static void main(String[] args) {
​
    }
    //单个字符读取
    @Test
    public void method01()  {
        String path = "F:\\悠然人生空岛v1.3更新内容.txt";
        FileReader fileReader = null;
        byte[] buf = new byte[8];
        int data = 0;
        try {
            fileReader = new FileReader(path);
            while ((data = fileReader.read()) != -1) {
                System.out.print((char) data);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            try {
                if (fileReader != null) {
                    fileReader.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
​
    //字符数组读取
    @Test
    public void method02()  {
        String path = "F:\\悠然人生空岛v1.3更新内容.txt";
        FileReader fileReader = null;
        char[] buf = new char[512];
        int readLen = 0;
        try {
            fileReader = new FileReader(path);
            while ((readLen = fileReader.read(buf)) != -1) {
                System.out.print(new String(buf,0,readLen));
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            try {
                if (fileReader != null) {
                    fileReader.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
3.5.2 FileWriter

FileWriter常用方法

  1. new FileWriter(File/String):覆盖模式,相当于流的指针在首段

  2. new FileWriter(File/String,true):追加模式,相当于流的指针在尾端

  3. write(int):写入单个字符

  4. write(char[]):写入指定数组

  5. write(char[],off,len):写入指定数组的指定部分

  6. write(String):写入整个字符串

  7. write(String,off,len):写入字符串的指定部分

  8. 相关API:String类:toCharArray:将String转换成char[]

注意:

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

package com.mdklea.file;
​
import org.junit.jupiter.api.Test;
​
import java.io.FileWriter;
import java.io.IOException;
​
@SuppressWarnings({"all"})
public class FileWriter_ {
    public static void main(String[] args) {
​
    }
​
    @Test
    public void writerMethod01() {
        String path = "F:\\悠然人生空岛v1.3更新内容.txt";
        FileWriter fileWriter = null;
​
        try {
            fileWriter = new FileWriter(path,true);
            fileWriter.write("风雨之后,定见彩虹");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        finally {
            if (fileWriter != null) {
                try {
                    fileWriter.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}

4.节点流和处理流

4.1 基本介绍

  1. 节点流可以从一个特定的数据源读写数据,如FileReader、FileWriter

  2. 处理流(也叫包装流)是"连接"在已存在的流(节点流或处理流)之上,为程序提供更为强大的读写功能,如BufferedReader、BufferedWriter

4.2 节点流和处理流的区别与联系

  1. 节点流是底层流/低级流,直接跟数据源相接。

  2. 处理流包装节点流,既可以消除不同节点流的实现差异,也可以提供更 方便的方法来完成输入输出。

  3. 处理流(也叫包装流)对节点进行包装,使用了修饰器设计模式,不会直接与数据源相连。

4.3 处理流的功能主要体现在一下两个方面:

  1. 性能的提高:主要以增加缓冲的方式来提高输入输出的效率。

  2. 操作的便捷:处理流可能提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便。

4.4 处理流-BufferedReader和BufferedWriter

BufferedReader和BufferedWriter属于字符串,是按照字符来读取数据的

关闭时,只关闭外层流即可

4.4.1 BufferedReader
package com.mdklea.buffered;
​
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
​
public class BufferedReader_ {
    public static void main(String[] args) throws IOException {
         String filePath = "F:\\悠然人生空岛v1.3更新内容.txt";
        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
        String line; //按行读取
        while ((line = bufferedReader.readLine()) != null) {
            System.out.println(line);
        }
​
        bufferedReader.close();
    }
}
4.4.2 BufferedWriter
package com.mdklea.buffered;
​
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
​
public class BufferedWriter_ {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("F:\\1.3更新内容.txt"));
        bw.write("老马最帅!");
        bw.newLine();
        bw.write("小马更帅!");
        bw.close();
    }
}
4.4.3 BufferedCopy
package com.mdklea.buffered;
​
import java.io.*;
​
public class BufferedCopy_ {
    public static void main(String[] args) throws IOException {
        String srcFilePath = "F:\\2必看!已知问题.txt";
        String destFilePath = "F:\\1.3更新内容.txt";
        String line;
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(destFilePath));
        BufferedReader bufferedReader = new BufferedReader(new FileReader(srcFilePath));
        while ((line = bufferedReader.readLine()) != null) {
            bufferedWriter.write(line);
            bufferedWriter.newLine();
        }
        bufferedReader.close();
        bufferedWriter.close();
    }
}

说明:

  1. BufferedReader 和 BufferedWriter 是按照字符操作

  2. 不要去操作二进制文件,可能造成文件损坏[声音,视频,doc,pdf],可能造成文件损坏

4.5 处理流-BufferedInputStream 和 BufferedOutputStream

4.5.1 BufferedInputStream
  • 介绍BufferedInputStream

    BufferedInputStream是字节流,在创建BufferedInputStream时,会创建一个内部缓冲区数组。

4.5.2 BufferedOutputStream
  • 介绍BufferedOutputStream

    BufferedOutputStream是字节流,实现缓冲的输出流,可以将多个字节写入底层输出流中,而不必对每次字节写入调用底层系统

4.5.3 拷贝图片
package com.mdklea.buffered;

import java.io.*;

public class BufferedCopy02 {
    public static void main(String[] args)  {
        String srcFile = "C:\\Users\\m1\\Pictures\\1.png";
        String destFile = "C:\\Users\\m1\\Pictures\\3.png";
        BufferedInputStream bufferedInputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        int readLine = 0;
        byte[] buff = new byte[1024];
        try {
            bufferedInputStream = new BufferedInputStream(new FileInputStream(srcFile));
            bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(destFile));

            while ((readLine = bufferedInputStream.read(buff)) != -1) {
                bufferedOutputStream.write(buff,0,readLine);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (bufferedInputStream != null) {
                try {
                    bufferedInputStream.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if (bufferedOutputStream != null) {
                try {
                    bufferedOutputStream.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}

4.6 对象流-ObjectInputStream 和 ObjectOutputStream

  • 看一个需求

    1. 将 int num = 100 这个 int 数据保存到文件中,注意不是100数字,而是int 100,并且,能够从文件中直接恢复 int 100

    2. 将 Dog dog = new Dog("小黄",3) 这个dog对象 保存到 文件中,并且能够从文件中恢复。

    3. 上面的要求就是能够将基本数据类型或者对象进行序列化和反序列化

  • 序列化和反序列化

    1. 序列化就是在保存数据时,保存数据的值和数据类型

    2. 反序列化就是在恢复数据时,恢复数据的值和数据类型

    3. 需要让某个对象支持序列化机制,则必须让其类时可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一:

      • Serializable //这是一个标记接口

      • Externalizable //该接口有方法需要实现,因此我们一般实现上面的接口

  • 基本介绍

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

    2. ObjectOutputStream 提供序列化功能

    3. ObjectInputStream 提供反序列化功能

4.6.1 ObjectInputStream
  • ObjectInputStream类图

    package com.mdklea.objectstream_;
    ​
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    ​
    @SuppressWarnings({"all"})
    public class ObjectOutputStream_ {
        public static void main(String[] args) {
            //序列化后保存的文件格式不是纯文本,而是按照他的格式来保存的
            String filePath = "F:\\data.dat";
            ObjectOutputStream objectOutputStream = null;
            try {
                objectOutputStream = new ObjectOutputStream(new FileOutputStream(filePath, true));
                objectOutputStream.writeInt(100);
                objectOutputStream.writeInt(200);
                objectOutputStream.writeDouble(11.1);
                objectOutputStream.writeUTF("马最帅");
                objectOutputStream.writeObject(new Dog("大黄",10));
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                if (objectOutputStream != null) {
                    try {
                        objectOutputStream.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }
    ​
    @SuppressWarnings({"all"})
    class Dog implements Serializable {
        private String name;
        private int age;
        private static final long serialVersionUID = 1L;
        //序列化的版本号,可以提高兼容性
    ​
        public Dog(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }
4.6.2 ObjectOutputStream
  • ObjectOutputStream类图

    package com.mdklea.objectstream_;
    ​
    ​
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    ​
    @SuppressWarnings({"all"})
    public class ObjectInputStream_ {
        public static void main(String[] args) {
            String filePath = "F:\\data.dat";
            ObjectInputStream objectInputStream = null;
            try {
                //注意读取顺序
                objectInputStream = new ObjectInputStream(new FileInputStream(filePath));
                System.out.println(objectInputStream.readInt());
                System.out.println(objectInputStream.readInt());
                System.out.println(objectInputStream.readDouble());
                System.out.println(objectInputStream.readUTF());
                Object dog = objectInputStream.readObject();
                System.out.println(dog);
                //如果我们希望调用Dog的方法,需要向下转型
                Dog dog2 = (Dog) dog;
                System.out.println(dog2.getName());
                System.out.println(dog2.getAge());
            } catch (IOException | ClassNotFoundException e) {
                throw new RuntimeException(e);
            } finally {
                if (objectInputStream != null) {
                    try {
                        objectInputStream.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
    ​
        }
    }
4.6.3 注意事项和细节要求
  1. 读写顺序要一致

  2. 要求序列化或反序列化对象,需要实现Serializable

  3. 序列化的类中建议添加 SerialVersionUID,为了提高版本的兼容性

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

  5. 序列化对象时,要求里面属性的类型也需要实现序列化接口

  6. 序列化具备可继承性,也就是如果某类已经实现了序列化,则它的所有子类也已经默认实现了序列化

4.7 标准输入输出流

介绍

4.7.1 System.in
  1. System 类的 public final static InputStream in = null;

  2. System.in 编译类型 InputStream

  3. System.in 运行类型 BufferedInputStream

  4. 表示的是标准输入-键盘

4.7.2 System.out
  1. System.out public final static PrintStream out = null;

  2. 编译类型 PrintStream

  3. 运行类型 PrintStream

  4. 表示标准输出-显示屏

4.8 转换流-InputStreamReader 和 OutputStreamWriter

介绍

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

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

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

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

4.8.1 InputStreamReader

类图

package com.mdklea.transformation_;
​
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
​
@SuppressWarnings({"all"})
public class InputStreamReader_ {
    public static void main(String[] args) {
         String filePath = "F:\\必看!已知问题.txt";
        FileInputStream fileInputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        try {
            fileInputStream = new FileInputStream(filePath);
            inputStreamReader = new InputStreamReader(fileInputStream,"UTF-8");
            bufferedReader = new BufferedReader(inputStreamReader);
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                System.out.println(line);
            }
​
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}

4.8.2 OutputStreamWriter

类图

4.9 打印流-PrintStream 和 PrintWriter

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

4.9.1 PrintStream

字节打印流

类图

package com.mdklea.printstream_;
​
import java.io.IOException;
import java.io.PrintStream;
​
public class PrintStream_ {
    public static void main(String[] args) throws IOException {
        PrintStream out = System.out;
        /*
        底层源码
        public void print(String s) {
            write(String.valueOf(s));
        }
         */
        //out.print("老骥伏枥,志在千里!");
        //print底层使用write方法
        try {
            out.write("老骥伏枥,志在千里!".getBytes());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        out.close();
​
        //我们可以修改打印流输出的位置/设备
​
        /*
        底层源码
        public static void setOut(PrintStream out) {
            checkIO();
            setOut0(out);   //native 方法 修改了out
        }
         */
        System.setOut(new PrintStream("F:\\f1.txt"));
        System.out.println("老马浮力,旨在潜力!");
    }
}

4.9.2 PrintWriter

字符打印流

类图

package com.mdklea.printstream_;
​
import java.io.IOException;
import java.io.PrintWriter;
​
public class PrintWriter_ {
    public static void main(String[] args) throws IOException {
        //PrintWriter printWriter = new PrintWriter(System.out);
        PrintWriter printWriter = new PrintWriter("F:\\f2.txt");
        printWriter.print("北京你好!");
        printWriter.close();
    }
}

4.10 Properties类

  • 看一个需求

    如下一个配置文件 mysql.properties

    ip = 192.168.0.13

    user = root

    pwd = 12345

    请问读取ip,user和pwd 的值是多少

  • 分析

    1. 传统的方法

      package com.mdklea.properties_;
      ​
      import java.io.BufferedReader;
      import java.io.FileReader;
      import java.io.IOException;
      ​
      public class Properties_ {
          public static void main(String[] args) throws IOException {
              //读取mysql.properties
              BufferedReader bufferedReader = new BufferedReader(new FileReader("src\\mysql.properties"));
              String line;
              while ((line = bufferedReader.readLine()) != null) {
                  String[] split = line.split("=");
                  System.out.println(split[0] + "值是" + split[1]);
              }
              bufferedReader.close();
          }
      }

    2. 使用Properties类可以方便实现

4.10.1 基本介绍

  1. 专门用于读写配置文件的集合

    配置文件的格式:

    键 = 值

    键 = 值

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

  3. Properties的常用方法

    load:加载配置文件的键值对到Properties对象

    list:将数据显示到指定设备

    getProperty(key):根据键获取值

    setProperty(key,value):设置键值对到Properties对象

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

package com.mdklea.properties_;
​
import java.io.*;
import java.util.Properties;
​
public class Properties_02 {
    public static void main(String[] args) throws IOException {
        Properties properties = new Properties();
        BufferedReader bufferedReader = new BufferedReader(new FileReader("src\\mysql.properties"));
        properties.load(bufferedReader);
        properties.list(System.out);
        properties.setProperty("ip","192.168.1.1");
        System.out.println(properties.getProperty("ip"));
    }
}
package com.mdklea.properties_;
​
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
​
@SuppressWarnings({"all"})
public class Properties_03 {
    public static void main(String[] args) throws IOException {
        Properties properties = new Properties();
        //创建
        //1. 如果该文件没有key 就是创建
        //2. 如果该文件有key 就是修改
        /*
        Propetties 父类是 Hashtable 底层就是Hashtable  核心方法
        public synchronized V put(K key, V value) {
            // Make sure the value is not null
            if (value == null) {
                throw new NullPointerException();
            }
​
            // Makes sure the key is not already in the hashtable.
            Entry<?,?> tab[] = table;
            int hash = key.hashCode();
            int index = (hash & 0x7FFFFFFF) % tab.length;
            @SuppressWarnings("unchecked")
            Entry<K,V> entry = (Entry<K,V>)tab[index];
            for(; entry != null ; entry = entry.next) {
                if ((entry.hash == hash) && entry.key.equals(key)) {
                    V old = entry.value;
                    entry.value = value; //如果key存在就替换
                    return old;
                }
            }
​
            addEntry(hash, key, value, index);
            return null;
        }
         */
        properties.setProperty("charset","UTF-8");
        properties.setProperty("user","汤姆");
        properties.setProperty("pwd","abc123");
        properties.store(new FileOutputStream("src\\mysql2.proterties"),null);
        System.out.println("保存配置文件成功!");
​
    }

5. 本章作业

5.1

package com.mdklea.homework;
​
import java.io.*;
​
@SuppressWarnings({"all"})
public class HomeWork01 {
    public static void main(String[] args) {
        BufferedOutputStream bufferedOutputStream = null;
        File file = new File("F:\\mytemp");
        if (file.exists()) {
            System.out.println(file + "已存在!");
        }else {
            if (file.mkdir()) {
                System.out.println("创建成功!");
            }else {
                System.out.println("创建失败!");
            }
        }
        File file1 = new File("F:\\mytemp\\hello.txt");
        if (file1.exists()) {
            System.out.println(file1 + "已存在!");
        }else {
            try {
                file1.createNewFile();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        try {
            bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file1));
            bufferedOutputStream.write("hello,world ~".getBytes());
​
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (bufferedOutputStream != null) {
                try {
                    bufferedOutputStream.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("输入成功!");
            }
        }
    }
}

5.2

package com.mdklea.homework;
​
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
​
public class HomeWork02 {
    public static void main(String[] args) {
        String filePath = "F:\\1.18领主整合包\\游玩须知.txt";
        BufferedReader bufferedReader = null;
        try {
            bufferedReader = new BufferedReader(new FileReader(filePath));
            String readLine;
            int count = 0;
            while ((readLine = bufferedReader.readLine()) != null) {
                System.out.println((++count) + ". " + readLine);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
package com.mdklea.homework;
​
import java.io.*;
​
@SuppressWarnings({"all"})
public class HomeWork02_2 {
    public static void main(String[] args) throws IOException {
        String filePath = "F:\\1.18领主整合包\\游玩须知.txt";
        InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(filePath),"gbk");
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String readLine;
        int count = 0;
        while ((readLine = bufferedReader.readLine()) != null) {
            System.out.println((++count) + ". " + readLine);
        }
        bufferedReader.close();
    }
}

5.3

package com.mdklea.homework;
​
import org.junit.jupiter.api.Test;
​
import java.io.*;
import java.util.Properties;
@SuppressWarnings({"all"})
public class HomeWork03 {
    public static void main(String[] args) throws IOException {
        Properties properties = new Properties();
        properties.setProperty("name","tom");
        properties.setProperty("age","5");
        properties.setProperty("color","red");
        properties.store(new FileWriter("src\\dog.properties"),null);
        String name = properties.get("name") + "";
        int age = Integer.parseInt(properties.get("age") + "");
        String color = properties.get("color") + "";
        Dog dog = new Dog(properties.getProperty("name"), Integer.parseInt(properties.getProperty("age")), properties.getProperty("color"));
        System.out.println(dog);
​
        //序列化
        String serFilePath = "F:\\dog.dat";
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(serFilePath));
        objectOutputStream.writeObject(dog);
        objectOutputStream.close();
        System.out.println("序列化完成");
​
    }
    //反序列化
    @Test
    public void m1() throws IOException, ClassNotFoundException {
        String serFilePath = "F:\\dog.dat";
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(serFilePath));
        System.out.println(objectInputStream.readObject());
    }
}
@SuppressWarnings({"all"})
class Dog implements Serializable {
    private String name;
    private int age;
    private String color;
​
    public Dog(String name, int age, String color) {
        this.name = name;
        this.age = age;
        this.color = color;
    }
​
    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", color='" + color + '\'' +
                '}';
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值